PythonでCSVを読み込んでDBにインポートするコードを書いています。1回の実行で何度もランダムアクセスする必要があるため最初にCSVを全て読みんで辞書に格納しておき、それ以降はその辞書から値を探して返すようにしたいです。
そのキャッシュをグローバル空間に置くのは何なのでクラス変数を使おうと以下のように実装しました。
python
1"""class変数を使ったコード.""" 2import csv 3 4csv_content = """だいこん,128 5にんじん,38 6たまねぎ,38 7なす,48 8きゅうり,28""" 9 10 11class Yasai(object): 12 @classmethod 13 def _load_csv(cls): 14 if not hasattr(cls, 'caches'): 15 print('init') 16 cls.caches = {row[0]: row[1] for row in csv.reader(csv_content.split())} 17 18 @classmethod 19 def get_price(cls, item): 20 cls._load_csv() 21 return cls.caches.get(item) or None 22 23 24>>> from hoge import Yasai 25>>> Yasai.get_price('にんじん') 26init 27'38' 28>>> Yasai.get_price('にんじん') 29'38'
やりたいことは実現できているのですが、少し実装がおおげさに感じます。
調べたところ関数の結果をキャッシュするデコレーター:memonize というテクニックがあることを知りましたが、恥ずかしながらデコレーターを理解しきれておらず、これまた変なコードになってしまいました。またファイル(モジュール)をインポートしただけで初回ロードが走るのも少し気になります。
python
1"""みようみまねでデコレータを使ったコード.""" 2def _yasai_cache(func): 3 print('init') 4 caches = {row[0]: row[1] for row in csv.reader(csv_content.split())} 5 def __yasai_cache(item): 6 return caches.get(item) or None 7 return __yasai_cache 8 9@_yasai_cache 10def get_price(yasai): 11 pass 12 13 14>>> from hoge import get_price 15init 16>>> get_price('にんじん') 17'38' 18>>> get_price('にんじん') 19'38'
もう少しシンプルな実装やセオリー(デザインパターン?)はあれば教えてください。
なお実際は複数のCSVを比較したりチェックしたりしながらインポートを行っているため、CSVまるごとDBにえいやと入れたりすることはできません。
※今のクラス変数を使う方法でいいんじゃない?という場合もその旨を回答いただけると幸いです。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/09/18 14:32