Python
参考文献
- #strftime-strptime-behavior に strptime() の書式コードがある。
Snippets
コンテキストマネージャ型
import http.client
import json
class MyClient:
def __init__(self, host='localhost', port=8080):
self.host = host
self.port = port
def __enter__(self):
self.conn = http.client.HTTPConnection(self.host, self.port)
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.conn.close()
def get(self, url):
self.conn.request('GET', url)
resp = self.conn.getresponse()
if resp.status == 200:
data = json.loads(resp.read().decode())
return data
else:
raise Exception(f'Failed: {resp.status} {resp.reason}')
with MyClient() as cli:
data = cli.get('/bentou?type=A')
print(data)
contextlib.contextmanager デコレータ
import http.client
import json
from contextlib import contextmanager
@contextmanager
def my_connection(host='localhost', port=8080):
conn = http.client.HTTPConnection(host, port)
try:
yield conn
finally:
conn.close()
with my_connection() as conn:
conn.request('GET', '/bentou?type=A')
resp = conn.getresponse()
data = json.loads(resp.read().decode())
print(data)
フィボナッチ数列を返すイテレータオブジェクト
イテレータオブジェクトの構成プロトコルは、イテレータオブジェクト自体を返す
__iter__()
と次のアイテムを返す
__next__()
とのことなので[2]、これらのメソッドを実装する。以下のイテレータオブジェクトは100に達するまでフィボナッチ数列を出力する。
class Fibonacci:
def __iter__(self):
print('===== __iter__() was just called. =====')
self.a = 0
self.b = 0
return self
def __next__(self):
if self.b >= 100:
raise StopIteration()
if self.b == 0:
c = 1
elif self.a == 0:
c = 1
else:
c = self.a + self.b
self.a = self.b
self.b = c
return c
fi = Fibonacci()
for x in fi:
print(x)
for x in fi: # 2回目も可能.
print(x)
===== __iter__() was just called. =====
1
1
2
3
5
8
13
21
34
55
89
144
===== __iter__() was just called. =====
1
1
2
3
5
8
13
21
34
55
89
144
いくつに達したら終わるかを毎回変更することもできる。
import random
class Fibonacci:
def __iter__(self):
print('===== __iter__() was just called. =====')
self.a = 0
self.b = 0
self.threshold = random.choices([5, 10, 20, 30])[0]
return self
def __next__(self):
if self.b >= self.threshold:
raise StopIteration()
if self.b == 0:
c = 1
elif self.a == 0:
c = 1
else:
c = self.a + self.b
self.a = self.b
self.b = c
return c
文字列を datetime 型に変換しユニックス秒に変換する
datetime.datetime.strptime() で datetime 型にできる。timestamp() メソッドでユニックス秒にできる。タイムゾーン情報をパースしないと datetime 型は自分のタイムゾーンについて無知になる。その場合でも timestamp() メソッドではシステムのタイムゾーンが適用される。タイムゾーン情報をパースさせれば datetime 型は自分のタイムゾーンを認識する。日本時間の1時より協定世界時の1時の方が未来である。
import datetime
s = '2022-03-13 01:23:45'
dt = datetime.datetime.strptime(s, '%Y-%m-%d %H:%M:%S') # naive
ts = dt.timestamp() # ここでローカル時刻として UNIX 秒化される
print(dt, dt.tzinfo)
print(ts)
print(datetime.datetime.fromtimestamp(ts))
s = '2022-03-13 01:23:45+09:00'
dt = datetime.datetime.strptime(s, '%Y-%m-%d %H:%M:%S%z') # aware
ts = dt.timestamp()
print(dt, dt.tzinfo, dt.tzinfo.utcoffset(dt))
print(ts)
print(datetime.datetime.fromtimestamp(ts))
s = '2022-03-13 01:23:45+00:00'
dt = datetime.datetime.strptime(s, '%Y-%m-%d %H:%M:%S%z') # aware
ts = dt.timestamp()
print(dt, dt.tzinfo, dt.tzinfo.utcoffset(dt))
print(ts)
print(datetime.datetime.fromtimestamp(ts))
2022-03-13 01:23:45 None
1647102225.0
2022-03-13 01:23:45
2022-03-13 01:23:45+09:00 UTC+09:00 9:00:00
1647102225.0
2022-03-13 01:23:45
2022-03-13 01:23:45+00:00 UTC 0:00:00
1647134625.0
2022-03-13 10:23:45
上のコードに示しているように datetime.datetime.fromtimestamp() でユニックス秒から datetime 型を復元できるが、このとき明示的にタイムゾーンを指定しないと datetime 型は自分のタイムゾーンについて無知になる。
ts = 1647102225.0
dt = datetime.datetime.fromtimestamp(ts)
print(dt, dt.tzinfo)
dt = datetime.datetime.fromtimestamp(ts, datetime.timezone(datetime.timedelta(hours=9)))
print(dt, dt.tzinfo)
dt = datetime.datetime.fromtimestamp(ts, datetime.timezone(datetime.timedelta(hours=0)))
print(dt, dt.tzinfo)
2022-03-13 01:23:45 None
2022-03-13 01:23:45+09:00 UTC+09:00
2022-03-12 16:23:45+00:00 UTC