Python のスニペット集

このページは、Python (3) のスニペットなどをまとめる予定のページです。

目次

注意

  • コードのライセンスは CC0 (クレジット表示不要、改変可、商用可) です。

スニペット

文字列

フォーマット

フォーマット文字列
a = 1
b = 2
s = f'a = {a}, b = {b}'
書式化演算子
a = 1
b = 2
s = 'a = %d, b = %d' % (a, b)
テンプレート文字列
# from string import Template

s = Template('a = $a, b = $b')
s.substitute({'a': 1, 'b': 2})

list

要素の削除

del
list1 = [1, 2, 3]
del list1[1]
pop
list1 = [1, 2, 3]
list1.pop(1)

dict

dict のマージ

d1 = {'a': 1, 'b': 2}
d2 = {'c': 3, 'd': 4}

d3 = {**d1, **d2}
d4 = d1 | d2
d5 = {**d1, 'e': 5, 'f': 6}
Python 3.9 以降
d1 = {'a': 1, 'b': 2}
d2 = {'c': 3, 'd': 4}

d3 = d1 | d2

一部のキーのみの dict を取得

d = {'a': 1, 'b': 2, 'c': 3}
keys = ['a', 'b']
d2 = {k:v for k, v in d.items() if k in keys}

日時

現在日時

# from datetime import datetime
dt = datetime.now()
タイムゾーン指定 (UTC。datetime.utcnow() だと tzinfo が設定されません)
# from datetime import datetime, timezone
tz = timezone.utc
dt = datetime.now(tz)
タイムゾーン指定 (JST +9:00)
# from datetime import datetime, timezone, timedelta
jst = timezone(timedelta(hours=+9))
dt = datetime.now(jst)
タイムゾーン指定 (あとから)
# from datetime import datetime, timezone
dt = datetime.now()
tz = timezone.utc
dt2 = dt.astimezone(tz)

フォーマット

YYYY-MM-DD HH:MM:SS
# from datetime import datetime, timezone
dt.strftime("%Y-%m-%d %H:%M:%S")

経過時間

# import time
start = time.time()
# 処理 ...
elapsed = time.time() - start

正規表現

英数
# import re
s = 'abc123'
result = re.fullmatch('[a-zA-Z0-9]+', s)
英数記号
# import re
s = 'abc123!'
symbol = '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
result = re.fullmatch('[a-zA-Z0-9%s]+' % re.escape(symbol), s)

UUID

# import uuid
uuid_str = str(uuid.uuid1())

ファイル

タイムスタンプ変更

# import time
# import os

t = time.mktime((2019, 1, 1, 0, 0, 0, 0, 0, 0)) # 2019-01-01 00:00:00
os.utime('file.txt', (t, t))

sleep

1秒待つ
# import time
time.sleep(1)

パス

実行パスからの相対パス解決

# import pathlib
p = str(pathlib.Path(__file__).parent.joinpath('path/to/file.txt')) # /example/test/main.py で動作している場合 /example/test/path/to/file.txt

URL

パス結合

# from urllib.parse import urljoin
p = urljoin('https://exmaple.com/api/', 'path/to/file.txt')

JSON

エンコード

# import json
print(json.dumps(data))

デコード

# import json
data = json.loads('[1,2,3]')

INI

読み込み

ini ファイルの例 (settings.ini)
[section1]
value1=1
# import configparser

config = configparser.ConfigParser()
config.read('settings.ini')
value1 = config['section1']['value1']

書き込み

# import configparser

config = configparser.ConfigParser()
config['a'] = {}
config['a']['b'] = "c"
with open('settings.ini', 'w') as f:
   config.write(f)

HTTP

GET

# import urllib.request

url = 'https://example.com/'
headers = {
    'Accept-Language': 'ja',
}
data = {
    'foo': 1
}
req = urllib.request.Request(f'{url}?{urllib.parse.urlencode(data)}', None, headers)
with urllib.request.urlopen(req) as res:
    body = res.read().decode('utf-8')
    print(body)

GET (SSL の検証無効化)

# import urllib.request
# import ssl

url = 'https://example.com/'
headers = {
    'Accept-Language': 'ja',
}
data = {
    'foo': 1
}
req = urllib.request.Request(f'{url}?{urllib.parse.urlencode(data)}', None, headers)
context = ssl.create_default_context() # SSL のコンテキストを生成
context.check_hostname = False # ホスト名のチェックを無効化
context.verify_mode = ssl.CERT_NONE # 検証無効化
with urllib.request.urlopen(req, context=context) as res:
    body = res.read().decode('utf-8')
    print(body)
  • POST の場合も同じように urlopen() にコンテキストを渡します。

GET (エラー制御)

url = 'https://example.com/'
headers = {
    'Accept-Language': 'ja',
}
data = {
    'foo': 1
}

try:
    req = urllib.request.Request(f'{url}?{urllib.parse.urlencode(data)}', None, headers)
    with urllib.request.urlopen(req) as res:
        body = res.read().decode('utf-8')
        print(body)
except urllib.error.HTTPError as e:
    # e.code に数値型でステータスコードが格納されている
    print(e)

POST

# import urllib.request

url = 'https://example.com/'
headers = {
    'Accept-Language': 'ja',
}
data = {
    'foo': 1
}
req = urllib.request.Request(url, urllib.parse.urlencode(data).encode(), headers)
with urllib.request.urlopen(req) as res:
    body = res.read().decode('utf-8')
    print(body)

POST (JSON)

# import urllib.request
# import json

url = 'https://example.com/'
headers = {
    'Content-Type': 'application/json',
}
data = {
    'foo': 1
}
req = urllib.request.Request(url, json.dumps(data).encode(), headers)
with urllib.request.urlopen(req) as res:
    body = res.read().decode('utf-8')
    resData = json.loads(body)
    print(resData)

TCP

データの受信 (クライアント側)

socket.create_connection()
# import socket

host = '127.0.0.1'
port = 4000
timeout = 5
with socket.create_connection((host, port), timeout) as sock:
    res = sock.recv(1024)
    print(repr(res))
sock.connect()
# import socket

host = '127.0.0.1'
port = 4000
timeout = 5
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
    sock.settimeout(timeout)
    sock.connect((host, port))
    res = sock.recv(1024)
    print(repr(res))

ログ

ロガーの設定 (コンソール)

# import logging
# import logging.handlers

loglevel = logging.DEBUG  # ログレベル
logger = logging.getLogger(__name__)  # ロガー生成

logger.setLevel(loglevel)  # ログレベル設定
handler = logging.StreamHandler()  # 出力ハンドラ (コンソール)
handler.setLevel(loglevel)  # ログレベル設定
handler.setFormatter(logging.Formatter(
    '%(asctime)s %(name)s [%(levelname)s] %(message)s'))  # 出力フォーマット設定
logger.addHandler(handler)  # 出力ハンドラのセット

ロガーの設定 (ファイル)

# import logging
# import logging.handlers

loglevel = logging.DEBUG  # ログレベル
logger = logging.getLogger(__name__)  # ロガー生成

logger.setLevel(loglevel)  # ログレベル設定
handler = logging.FileHandler('log.log')  # 出力ハンドラ (ファイル)
handler.setLevel(loglevel)  # ログレベル設定
handler.setFormatter(logging.Formatter(
    '%(asctime)s %(name)s [%(levelname)s] %(message)s'))  # 出力フォーマット設定
logger.addHandler(handler)  # 出力ハンドラのセット

ロガーの設定 (ファイル + ローテート)

log.log にログ出力 (古いログは log.log.YYYYMMDD に移動)
# import logging
# import logging.handlers

loglevel = logging.DEBUG  # ログレベル
logger = logging.getLogger(__name__)  # ロガー生成

logger.setLevel(loglevel)  # ログレベル設定
handler = logging.handlers.TimedRotatingFileHandler('log.log')  # 出力ハンドラ (ファイル)
handler.suffix = "%Y%m%d" # ログの後ろにセットする日付フォーマット
handler.setLevel(loglevel)  # ログレベル設定
handler.setFormatter(logging.Formatter(
    '%(asctime)s %(name)s [%(levelname)s] %(message)s'))  # 出力フォーマット設定
logger.addHandler(handler)  # 出力ハンドラのセット

ロガーの設定 (設定ファイルから設定)

設定ファイル (logconfig.json)
{
    "version": 1,
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "DEBUG",
            "formatter": "custom"
        },
        "file": {
            "class": "logging.handlers.TimedRotatingFileHandler",
            "level": "DEBUG",
            "filename": "log.log",
            "when": "MIDNIGHT",
            "formatter": "custom"
        }
    },
    "formatters": {
        "custom": {
            "format": "%(asctime)s %(name)s [%(levelname)s] %(message)s"
        }
    },
    "root": {
        "handlers": ["console", "file"],
        "level": "DEBUG"
    }
}
# import logging
# import logging.config
# import json

with open('logconfig.json') as f:
    config = json.load(f)

logging.config.dictConfig(config)
logger = logging.getLogger(__name__)

ロガーの設定 (設定ファイルから設定 + カスタムハンドラ)

設定ファイル (logconfig.json。file.class を独自のハンドラクラスにしています)
{
    "version": 1,
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "DEBUG",
            "formatter": "custom"
        },
        "file": {
            "class": "logging.handlers.CustomTimedRotatingFileHandler",
            "level": "DEBUG",
            "filename": "log.log",
            "when": "MIDNIGHT",
            "formatter": "custom"
        }
    },
    "formatters": {
        "custom": {
            "format": "%(asctime)s %(name)s [%(levelname)s] %(message)s"
        }
    },
    "root": {
        "handlers": ["console", "file"],
        "level": "DEBUG"
    }
}
# import logging
# import logging.config
# import re
# import json

class CustomTimedRotatingFileHandler(logging.handlers.TimedRotatingFileHandler):
    """独自のハンドラクラスです。ファイル形式を log.log.YYYY-MM-DD などから log.YYYYMMDD.log に変更します。
    """

    def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None):
        logging.handlers.TimedRotatingFileHandler.__init__(self, filename, when, interval,
                                                           backupCount, encoding, delay, utc, atTime)

        if self.when == 'S':
            self.suffix = "%Y%m%d%H%M%S"
        elif self.when == 'M':
            self.suffix = "%Y%m%d%H%M"
        elif self.when == 'H':
            self.suffix = "%Y%m%d%H"
        elif self.when == 'D' or self.when == 'MIDNIGHT':
            self.suffix = "%Y%m%d"
        elif self.when.startswith('W'):
            self.suffix = "%Y%m%d"

        def namer(default_name):
            return re.sub(r'log\.([0-9]+)', r'\1.log', default_name)
        self.namer = namer


logging.handlers.CustomTimedRotatingFileHandler = CustomTimedRotatingFileHandler


with open('logconfig.json') as f:
    config = json.load(f)

logging.config.dictConfig(config)
logger = logging.getLogger(__name__)

ロガーの使用

# logger は上記で作成したロガーです

logger.debug('debug')
logger.info('info')
logger.warning('warning')
logger.error('error')
logger.critical('critical')
try:
    raise Exception("exception")
except Exception as e:
    logger.exception(e)