pythonでJSONが繋がっているようなファイルを読み込む方法。
json.loadsは使えない
例えば以下の様なデータが在る場合がある。
{"name": "foo"} {"name": "bar"} {"name": "boo"}
通常の方法ではinvalidなJSONなので読み込めない。
import json s = """ {"name": "foo"} {"name": "bar"} {"name": "boo"} """ print(json.loads(s))
エラーになる。json.loads
は使えない。
json.decoder.JSONDecodeError: Extra data: line 3 column 1 (char 17)
json.jSONDecoderのraw_decodeを使う
以下の様な関数を定義してあげる。ジェネレーターである必要はあんまりない。
import json from json.decoder import WHITESPACE def loads_iter(s): size = len(s) decoder = json.JSONDecoder() end = 0 while True: idx = WHITESPACE.match(s[end:]).end() i = end + idx if i >= size: break ob, end = decoder.raw_decode(s, i) yield ob
今度は大丈夫。
s = """ {"name": "foo"} {"name": "bar"} {"name": "boo"} """ print(list(loads_iter(s))) # [{'name': 'foo'}, {'name': 'bar'}, {'name': 'boo'}]
もちろん以下の様な崩れた一行に収まらない状態でも問題なし。
s = """ {"name": "foo"} { "name": "bar" } { "name": "boo" } """ print(list(loads_iter(s))) # [{'name': 'foo'}, {'name': 'bar'}, {'name': 'boo'}]
pythonでサブクラスを定義するときにオプションを渡せるようにしてみる
そういえば、継承時にbase classの他にオプションを取る定義が書けるのわりと最初ビックリするけれどvalidなpythonのコード。
3.6なら__init_subclass__
のフックを使うのが楽かもしれない。
たとえば、以下の様なコードを書いてみる。
- 自身を継承したクラスをchildrenという変数に格納する
- 継承時にnameというオプションを与えた時にはかわりにその名前を格納する
3.6の場合
3.6以降の場合
class A: children = set() def __init_subclass__(cls, name=None): name = name or cls.__name__ cls.children.add(name) class B(A): pass class C(A, name="MaybeA"): pass print(A.children) # {'B', 'MaybeA'}
3.6以前の場合
メタクラスを使って対応することもできる。ただ自分自身を格納しないようにするのがちょっとトリッキー
class AMeta(type): def __new__(self, clsname, bases, attrs, name=None): instance = super().__new__(self, clsname, bases, attrs) if "children" not in instance.__dict__: instance.children.add(name or clsname) return instance class A(metaclass=AMeta): children = set() class B(A): pass class C(A, name="MaybeA"): pass print(A.children) # {'B', 'MaybeA'}