豊橋技術科学大学の近藤です。
pythonをあまり触ってこなかった私が、
躓いた点、気を付けるるべきと思った点をまとめてみました。
printでのロギングはよろしくないということなので、Loggerについて調べてみました。
基本的な使い方
printだと改行させずにログをだし、処理が終わったらステータスを出して改行する
のような使い方ができたが、loggerでは難しいようで。
python ver3.2以降であれば、stream_handler.terminatorに改行コード
が入っているので、空文字にしてやれば改行されないらしい。
を使っていたが、subprocess.Popenのほうが出力等の制御がしやすく、
Ctrl-cが送られてきた際にも処理を止めてくれたりするので使ってみました。
同時に消すには、deleteのオーバーライドか、レシーバを使う
with を使うと書かないでよい。以下、zip_target内のファイルを圧縮するコード。
pythonをあまり触ってこなかった私が、
躓いた点、気を付けるるべきと思った点をまとめてみました。
Logger
Djangoで使うコマンドを作成した際、ログ表示にprintを使っていましたが、printでのロギングはよろしくないということなので、Loggerについて調べてみました。
基本的な使い方
import logging
logger = logging.getLogger('hoge.command')
logger.setFormatter(logging.Formatter('HogeCommand:%(message)s'))
logger.setLevel(logging.DEBUG)
logger.info('fuga')
ログのレベルはDEBUG < INFO < WARNING < ERROR < CRITICALの順。設定レベル以下のログは出ない
printだと改行させずにログをだし、処理が終わったらステータスを出して改行する
のような使い方ができたが、loggerでは難しいようで。
python ver3.2以降であれば、stream_handler.terminatorに改行コード
が入っているので、空文字にしてやれば改行されないらしい。
Exception.message @ version2.6
except Exception as e: logger.warning(e.message)Filepython 2.6だと怒られるので、
logger.warning(e) logger.warning(e[0]) logger.warning(e.args[0]) logger.warning(e.str())のどれかでOK。ただ、e.str()だとUTF-8が化けるので注意。
Popen
os側のコマンドをたたく際に、os.systemや、commands.getstatusoutputを使っていたが、subprocess.Popenのほうが出力等の制御がしやすく、
Ctrl-cが送られてきた際にも処理を止めてくれたりするので使ってみました。
# 実行したいコマンドを準備
# コマンドはスペース区切りでリスト化する
# shlex.splitが便利
cmd = shlex.split('ls -la | grep hoge')
# コマンド実行
# stdout,stderrを指定しないとコンソールに垂れ流し
# いらないよ!というときは、open(os.devnull, 'w')を渡せばOK
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, strerr=subprocess.PIPE)
try:
# 処理完了を待って、出力を受け取る
# ここで、inputを渡せたりもする
# 引数にTimeoutがあるので一応10秒を渡しておく
(stdout, stderr) = process.communicate(10)
except:
# タイムアウト等、python側のエラー時の処理
# プロセスを殺して処理を止める
process.kill()
raise
# 終了ステータスがprocess内に設定されている
if process.returncode != 0:
hoge
FileField
ファイルフィールドのファイルはインスタンスが消されても消えないので注意同時に消すには、deleteのオーバーライドか、レシーバを使う
def delete(self, *args, **kwargs):
if self.file and os.path.isfile(self.file.path):
os,remove(self.file.path)
super(Hoge, self).delete(*args, **kwargs)
@receiver(models.signals.post_delete, sender=Hoge)
def auto_delete_file_on_delete(sender, instance, **kwargs):
if instance.file and os.path.isfile(instance.file.path):
os.remove(instance.file.path)
with
ファイルを開いたら、必ず閉じる処理を書かないといけないと思っていたが、with を使うと書かないでよい。以下、zip_target内のファイルを圧縮するコード。
zip_file = zipfile.ZipFile(zippath, 'w', zipfile.ZIP_DEFLATED) for filepaht, name in zip_targets: zip_file.write(filepath, name) zip_file.close()がwithをつかうと以下
with zipfile.ZipFile(zippath, 'w', zipfile.ZIP_DEFLATED) as zip_file:
for filepaht, name in zip_targets:
zip_file.write(filepath, name)
コード1行節約ができ、見た目がすっきりした。
コメント
コメントを投稿