2017-12-19 41 views
0

で、オプションのコンテキストマネージャを実装します。我々は以下の使用パターンとコードベースを持っているのPython

factory = DataFactory(args) 
dataset = factory.download_and_cache_big_dataset(key) 
metadata = dataset.get_some_metadata() 

現在、download_and_cache_big_datasetはS3からの非常に大きなファイルを取得し、どこかにそれを置きます。とりわけ、

filename = get_s3_key(key) 
filepath = os.path.join(get_tmp_dir(), filename) 
s3.download_file(key, filepath) 
return BigFileClass(filepath) # gets stored in a class somewhere 

ただし、このファイルは削除されません。この関数が控えめに呼び出され、ファイルキャッシングに依存している場合は問題ありませんが、繰り返し呼び出されてディスクをいっぱいにしたくない場合は悪いです。であるように、他のコードが動作するように我々は、既存の利用状況を壊すことなく

factory = DataFactory(args) 
with factory.download_and_cache_big_dataset(key) as dataset: 
    metadata = dataset.get_some_metadata() 
    # do something with metadata 

# file gets automatically deleted 

しかし、批判的に、としてそれを使用することができるようにcontext managerでコードをリファクタリングする方法はありますか?あるいは、コンテキストマネージャを返す別のメソッドが必要になるでしょうか?

+0

ファイルを作成するコードと、自動的にファイルを削除するように実行するコードの例を挙げることができますか? – quamrana

+0

@quamrana確かに更新されました。 –

+0

[使用後にファイルを削除するために 'with'を使用する] Pythonの重複の可能性あり(https://stackoverflow.com/questions/5019209/python-using-with-to-delete-a-file-after-use) – quamrana

答えて

1

データを処理/表現するためにBigFileClassのインスタンスを返すので、私は以下を提案します。

私は、データファイルが各インスタンスに対して一意であると仮定しています。

  • BigFileClassにインスタンス変数を追加して、データファイルのパスを追跡します。
  • データファイルが削除されたBigFileClass__del__メソッドを追加します。

編集:あなたがcontextmanagerとしてBigFileClassを使用したい場合は、BigFileClassため__enter____exit__メソッドを定義します。この場合__enter__がしなければならないのは基本的にreturn selfです。

ファイルを__del__メソッド(BigFileClassの参照カウントが0になる場合)に削除する作業は任せます。すでにデータファイルを削除しても、クラスインスタンスがまだ周囲にあるのは間違いありません。


備考w.r.t.建築。

工場の使用は、私には不要な複雑さのようです。 IMO、download_and_cache_big_datasetは、BigFileClassインスタンスを返す関数に過ぎません。

+0

ファイルを 'with ... as dataset:'として使用し、 'dataset = ...'の古いスタイルではなく、ファイルを削除したい場合はどうすればいいですか? –

関連する問題