私はクラスを含むpythonスクリプトを持っています。del self vs self .__ del __() - そして、Pythonでクリーンアップする適切な方法は何ですか?
このクラスには、通常のクリーンアップのための__del__
メソッドがあります。スクリプトの通常の実行中にクラスを削除すると、クリーンアップが必要になります。
私はシグナルハンドラも持っていますが、それは異常なクリーンアップを行います。スクリプトがシグナルを受信したときに何か他のものを実行していた場合は、特別なクリーンアップを行い、続いて通常のクリーンアップを実行する必要があります。
del self
とself.__del__()
の間に違いがあることに気付きました。
つまり、self.__del__()
はdel
メソッドを2回呼び出します。
これがなぜ起こるのか説明してください。
これは、問題を説明するためのモックアップスクリプトです:
import sys
import signal
from optparse import OptionParser
class TestClass(object):
def __init__(self,
del_self):
self.del_self = del_self
print "__init__ with del_self = %s" % self.del_self
def __del__(self):
print "Now performing usual cleanup."
def signal_handler(self, arg_1, arg_2):
print "Received signal. Now performing unusual cleanup."
# Unusual cleanup
print "Did unusual cleanup"
if self.del_self:
print("Doing del self")
del self
else:
print("Doing self.__del__()")
self.__del__()
sys.exit(0)
if __name__ == '__main__':
arguments = sys.argv[1:]
parse = OptionParser("Test.")
parse.add_option(
"-d",
"--delself",
help="Set del self.",
type="int",
default=1
)
(options, _) = parse.parse_args()
print "Options: %s" % options
tc = TestClass(del_self=options.delself)
signal.signal(signal.SIGQUIT, tc.signal_handler)
while True:
pass
私はスクリプトを実行した場合:
python deltest.py --delself 1
そして問題killall -3 python
私が手:
Received signal. Now performing unusual cleanup.
Did unusual cleanup
Doing del self
Now performing usual cleanup.
として、もし私がpython deltest.py --delself 0
にもう一度killシグナルを送ると、私は得る:
Received signal. Now performing unusual cleanup.
Did unusual cleanup
Doing self.__del__()
Now performing usual cleanup.
Now performing usual cleanup.
この場合、__del__
メソッドが2回実行されるのはなぜですか?
ありがとうございます!
@ random_person_123:はい、これは詳細です[ここ](https://docs.python.org/2/reference/datamodel.html#object.__del__) –
したがって、正しく理解していることを確認してください__del__はガベージコレクションの開始時に呼び出されるため、シグナルハンドラで呼び出す必要はありません。インスタンスがガベージコレクションされたときに自動的に呼び出されるためです。これは正しいです? – mayk93
@ random_person_123:はい、決してそれを自分で呼び出すことはありません。オブジェクトがガベージコレクションされると自動的に呼び出されます。 CPythonは通常、最後の参照がなくなったときにそれを行いますが、正式にはPythonはオブジェクトのガベージコレクションを保証しません。 – RemcoGerlich