実行中のスクリプトのパスを取得
相対パス
# -*- coding:utf-8 -*-
import os
print(os.path.dirname(__file__))
絶対パス
# -*- coding:utf-8 -*-
import os.path
print(os.path.dirname(os.path.abspath(__file__)))
Logger
# -*- coding:utf-8 -*-
import logging
from logging import getLogger, FileHandler, StreamHandler, Formatter
import datetime
def my_logger(modname, log_filename=None, dry_run=False, log_format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'):
'''
ログ出力フォーマット設定
'''
handler_format = Formatter(log_format)
logger = getLogger(modname)
'''
loggerのログレベル設定(ハンドラに渡すエラーメッセージのレベル)
'''
logger.parent.setLevel(logging.DEBUG)
'''
ファイル出力
dry_run = Trueのときにはファイル出力しないようにする
'''
if log_filename and not dry_run:
file_handler = FileHandler(log_filename)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(handler_format)
logger.addHandler(file_handler)
'''
標準出力
'''
stream_handler = StreamHandler()
stream_handler.setLevel(logging.DEBUG)
stream_handler.setFormatter(handler_format)
logger.addHandler(stream_handler)
return logger
if __name__ == '__main__':
my_logger = my_logger('main', '/var/log/sample.log')
my_logger.debug('This is a debug log')
my_logger.info('This is a info log')
my_logger.warn('This is a warn log')
my_logger.error('This is a error log')
my_logger.critical('This is a critical log')
'''
2019-02-15 17:04:13,673 - main - DEBUG - This is a debug log
2019-02-15 17:04:13,674 - main - INFO - This is a info log
2019-02-15 17:04:13,674 - main - WARNING - This is a warn log
2019-02-15 17:04:13,674 - main - ERROR - This is a error log
2019-02-15 17:04:13,674 - main - CRITICAL - This is a critical log
'''
requestsでタイムアウト処理
# -*- coding:utf-8 -*-
import requests
from requests.packages.urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter
s = requests.Session()
'''
totalで5回リトライをする
backoff_factor=1の場合、リトライ間隔は、1回目は1秒、2回目は2秒、3回目は3秒・・・
status_forcelistで定義されたstatusのときのみリトライする
'''
retries = Retry(total=5,
backoff_factor=1,
status_forcelist=[ 500, 502, 503, 504 ])
s.mount('http://', HTTPAdapter(max_retries=retries))
s.mount('https://', HTTPAdapter(max_retries=retries))
'''
connection timeoutが10秒、read timeoutが30秒
'''
r = s.get('https://example.com/', timeout=(10.0, 30.0))
r.raise_for_status()
'''
response bodyを表示
'''
print(r.text)
'''
status codeを表示
'''
print(r.status_code)
シェルコマンド実行
# -*- coding:utf-8 -*-
import subprocess
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, stderr = proc.communicate()
print(proc.returncode)
print(stdout)
print(stderr)
subprocessで実行結果の標準出力をリアルタイムで表示する
import os
import sys
import subprocess
def run(cmd):
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while True:
line = proc.stdout.readline()
if line:
yield line
if not line and proc.poll() is not None:
break
def main():
for line in run('ls -l /'):
sys.stdout.buffer.write(line)
if __name__ == '__main__' :
main()
正規表現エスケープ
import re
re.escape('エスケープしたい文字列')
Template
テンプレートを作成
sample.tpl
Subject: ${subject}
Message: ${message}
テンプレートを元にファイルを生成する
# -*- coding:utf-8 -*-
from string import Template
template_file = 'sample.tpl'
t = Template(unicode(open(template_file).read(), 'utf-8', 'ignore'))
text = t.substitute({'subject' : 'タイトル', 'message' : 'メッセージ'})
print(text)
'''
Subject: タイトル
Message: メッセージ
'''
Pythonでシェルコマンドを実行する
subprocess
sample
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import subprocess
def execute_cmd(cmd):
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, stderr = proc.communicate()
return {'returncode': proc.returncode, 'stdout': stdout, 'stderr': stderr}
if __name__ == '__main__':
# 実行
cmd = 'whoami'
res = execute_cmd(cmd)
print(res)
'''
# 実行結果
{'returncode': 0, 'stderr': None, 'stdout': 'username\n'}
'''
リアルタイムで標準出力を取得する
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import subprocess
import os
import sys
def execute_cmd(cmd):
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while True:
line = proc.stdout.readline()
if line:
yield line
if not line and proc.poll() is not None:
break
if __name__ == '__main__':
cmd = 'top'
for line in execute_cmd(cmd):
sys.stdout.write(line)
Pythonでオプション付きのコマンドを作成する(argparse)
自作モジュール内でlogを出力する
Abstract with NotImplementedError for python3
SampleAbstractクラスで定義しているmust_be_implemented_method001
というメソッドは、継承先のクラスで必ず実装されていなければならない。
sample_class.py
# -*- coding:utf-8 -*-
from abc import ABCMeta, abstractmethod
class SampleAbstract(object, metaclass=ABCMeta):
@abstractmethod
def must_be_implemented_method001(self):
raise NotImplementedError()
class Sample(SampleAbstract):
def must_be_implemented_method001(self):
pass
def main(self):
pass
if __name__ == '__main__':
Sample()
もし継承先のSampleクラスでmust_be_implemented_method001
メソッドを実装せずに実行した場合、以下のエラーが発生する。
$ python sample_class.py
Traceback (most recent call last):
File "sample_class.py", line 18, in <module>
sample = Sample()
TypeError: Can't instantiate abstract class Sample with abstract methods must_be_implemented_method001
参考: https://note.nkmk.me/python-datetime-isoformat-fromisoformat/
datetime変換
UTC -> JSTに変換して、datetime型 -> string型に変換する。
$ pip install pytz
from pytz import timezone
# UTC -> JST
datetime_jst = timezone('Asia/Tokyo').localize(datetime_utc)
# datetime -> string
datetime_jst.strftime('%Y-%m-%d %H:%M:%S')
pyc -> pyに逆コンパイル
Python3で動きます。
$ pip install uncompyle6
sample.pycを逆コンパイル
$ uncompyle6 sample.pyc > sample.py