15

__del__が行うすべてのものをやってからではなく、はるかに強い保証(呼び出しはインタプリタが終了する前に行われる、と呼び出しの順序が明確に定義されていること、例えば、finalize保証など)とweakrefを防止する任意の障害はありますか?`weakref`コールバックが` __del__`を置き換えることができますか?

遠い過去には、it was thoughtのように、weakrefは、最終的に言語から__del__の削除につながると思われます。

何が起こるのを防ぎましたか?

few use cases for __del__と思われますが、私が知っていることはすべて、少なくともweakrefコールバックまたはweakref.finalizeで動作するように思われます。

更新:PEP 442

が劇的__del__の動作を改善し、@gzとの@ user2357112で言及weakrefとの懸念は、私は言語は、一般的に__del__は、より信頼性の高い作りに向けて動いている場合不思議、または向けましたよ__del__の代わりにweakref、またはその両方を使用してください。

+1

*「これが起こらないようにしたのは何ですか?」*これは、ごく少数の人が答えられるかもしれないという質問です。私はあなたが 'python-list'にこれを投稿し、うまくいけばいくつかのコア開発者の関心を引くことをお勧めします。 –

+2

Pythonのweakrefサポートはかなり悪いので、weakrefをweakrefにしたいと思うたくさんのオブジェクトタイプにすることはできません。これは普通あなたが書いている型には関係ありませんが、あなたの型が 'tuple'のようなものなら、それを弱めることはできません。 – user2357112

+1

また、weakrefコールバックは参照対象にアクセスできないため、より慎重な設計が必要です。 – user2357112

答えて

3

__del__はやや現実的な理由があります。 finalizeを含む幾つかの顕著なweakrefの改善は、new in Python 3.4であった。したがって、__del__をより良いweakrefsに置き換えると、py3kによる言語切替えの変更のウィンドウが表示されませんでした。

私が最もベースweakref機能によって置き換えることができますが、私が提案してfinalizeを実装issue 15528にリチャードオードケルクから、この観察に打たれています使用しています考える:

[Weakrefコールバック]低いですそれらを正しく使用する方法を検討するには、少し頭を傷つける必要があります。指示対象が死んだ後で、かつ、指示対象を誤って生き残らないようにするまで、weakrefを格納する場所を見つける必要があります。それでコールバックがweakrefを解放することを保証しなければなりません(残ったref-cyclesを残すことなく)。

オプションの場合、__del__メソッドを使用するほうがずっと面倒です。

とにかく、おそらく質問は、Python 4を検討しているときに再び浮かび上がるはずです。 ;)

1

実際にははユースケースに依存していますが、Pythonインタープリタのさまざまな実装ではCPythonと同じGC動作を持たないと考えることをお勧めします。

特にPyPyは、そのまますぐに-などのオブジェクトないコール__del__を行いdelは「いくつかの時間後に」-eletedまたは範囲の外に出るけどさ。そのため、CPythonの__del__の動作に依存するコードは、PyPyやその他の代替インタプリタで機能しなくなります。

withキーワードとともに__enter____exit__を使用することをお勧めします。例えば

from __future__ import print_function 

class MyClass(object): 

    def __enter__(self): 
     print("Entering") 

    def __exit__(self, exc_type, exc_val, exc_tb): 
     print("Exiting") 

# 'with MyClass()' can be used but want to show that 
# code in exit is executed regardless of object 
# life time 
obj = MyClass() 
with obj: 
    print("Stuff happening in between") 

結果は次のとおりです。

Entering 
Stuff happening in between 
Exiting 

文の上記の順序が保証され、GCの動作に依存しません。

withブロック内のコードが完了するとすぐに実行する必要があることは、通常、デストラクタクリアファイルハンドル、ロック解除などに入れられるものなど、__exit__に入ります。

オブジェクトの後にあるdelは、インタープリタの実装に応じてオブジェクトの参照を最終的にクリアしますが、すぐに実行する必要があるのはその動作に依存しないことです。

関連する問題