2

Python がファイル記述子を自動的に閉じることがわかりました。次のコードを実行し、lsofを使用して開いているファイルを見つけます。function でスリープするとopenAndSleep、ファイル「fff」がプロセスによって保持されていることがわかりました。しかし、機能を使い果たしたとき、ファイル「fff」はもう保持されていませんでした。

import time

def openAndSleep():
    f = open("fff", 'w')
    print "opened, sleep 10 sec"
    time.sleep(10)
    print "sleep finish"

openAndSleep()
print "in main...."
time.sleep(10000)

クラスファイルを確認しましたが、 __del__メソッドがありません。奇妙に思えますが、誰かそれについて何か知っていますか?

4

2 に答える 2

5

はい、CPython はそうします。

参照カウントが 0 になると、ファイル オブジェクトは自動的に閉じます。クリーンアップされるローカル スコープは、refcount が減少することを意味し、ローカル スコープが唯一の参照であった場合、ファイル オブジェクトの refcount は 0 に減少し、閉じられます。

ただし、ファイル オブジェクトをwithステートメント内のコンテキスト マネージャーとして使用し、そのように自動的に閉じることをお勧めします。CPython の特定のガベージ処理の実装を当てにしないでください。

def openAndSleep():
    with open("fff", 'w') as f:
        print "opened, sleep 10 sec"
        time.sleep(10)
        print "sleep finish"

__del__はカスタム Python クラスのフックであることに注意してください。ファイル オブジェクトは C で実装され、代わりにtp_deallocスロットを埋めます。このfile_dealloc()関数は、ファイル オブジェクトを閉じます。

ファイル オブジェクトを開いたままにしておく場合は、それへの参照がまだ残っていることを確認してください。それへの参照も別の場所に保存します。たとえば、関数から返して戻り値を格納するか、グローバルにするなどです。

于 2013-10-12T09:22:38.530 に答える
2

要するに:はい。

Python では、ガベージ コレクション メカニズムを実装することで、ユーザーがメモリを管理する必要がなくなります。これは基本的に、Python の各オブジェクトが自動的に解放され、誰も使用しない場合は削除され、後でプログラムで再び使用できるようにメモリとリソースを解放することを意味します。

ファイル オブジェクトは Python のオブジェクトであり、Python の他のオブジェクトと同じであり、ガベージ コレクターによって管理されます。関数スコープを離れると、ガベージ コレクターは (参照カウンターを使用して) 誰もファイルを使用していないことを確認し、オブジェクトを破棄します。つまり、オブジェクトも閉じます。

os.openこれを回避するためにできることは、Python ファイル オブジェクトではなくファイル記述子 (int) を返す whichを使用して、Python ファイル オブジェクトを使用せずにファイルを開くことです。ファイル記述子は、Python オブジェクトではなくオペレーティング システム オブジェクトであるため、ガベージ コレクターによって破棄されず、コードは機能します。ただし、後で fdを閉じる () ように注意する必要がありますos.close。そうしないと、リソースがリークし、遅かれ早かれプログラムがクラッシュします (プロセスは 1024 個のファイル記述子しか保存できず、それ以上ファイルを開くことができなくなります)。

追加情報:

http://www.digi.com/wiki/developer/index.php/Python_Garbage_Collection

于 2013-10-12T09:37:02.997 に答える