方法with
声明別名、コンテキストマネージャです:
class Foo(object):
def __init__(self):
self.bar = None
def __enter__(self):
if self.bar != 'open':
print 'opening the bar'
self.bar = 'open'
return self # this is bound to the `as` part
def close(self):
if self.bar != 'closed':
print 'closing the bar'
self.bar = 'close'
def __exit__(self, *err):
self.close()
if __name__ == '__main__':
with Foo() as foo:
print foo, foo.bar
が出力:
opening the bar
<__main__.Foo object at 0x17079d0> open
closing the bar
2)Pythonのオブジェクトをするとき、その参照カウント削除されますあなたの例ではdel foo
は最後の参照を削除しますので__del__
はすぐに呼び出されます。 GCにはこれには何も含まれていません。
class Foo(object):
def __del__(self):
print "deling", self
if __name__ == '__main__':
import gc
gc.disable() # no gc
f = Foo()
print "before"
del f # f gets deleted right away
print "after"
出力:
before
deling <__main__.Foo object at 0xc49690>
after
gc
は、あなたや他のほとんどのオブジェクトの削除とは何の関係もありません。これは、理由は、自己参照や循環参照のため、単純な参照カウントが動作しないときにクリーンアップするためにあります:
class Foo(object):
def __init__(self, other=None):
# make a circular reference
self.link = other
if other is not None:
other.link = self
def __del__(self):
print "deling", self
if __name__ == '__main__':
import gc
gc.disable()
f = Foo(Foo())
print "before"
del f # nothing gets deleted here
print "after"
gc.collect()
print gc.garbage # The GC knows the two Foos are garbage, but won't delete
# them because they have a __del__ method
print "after gc"
# break up the cycle and delete the reference from gc.garbage
del gc.garbage[0].link, gc.garbage[:]
print "done"
出力:
class Foo(object):
def __init__(self):
raise Exception
def __del__(self):
print "deling", self
if __name__ == '__main__':
f = Foo()
:
before
after
[<__main__.Foo object at 0x22ed8d0>, <__main__.Foo object at 0x22ed950>]
after gc
deling <__main__.Foo object at 0x22ed950>
deling <__main__.Foo object at 0x22ed8d0>
done
3)を見てみましょう
は:
Traceback (most recent call last):
File "asd.py", line 10, in <module>
f = Foo()
File "asd.py", line 4, in __init__
raise Exception
Exception
deling <__main__.Foo object at 0xa3a910>
オブジェクトは__new__
で作成され、__init__
にはself
と渡されます。 __init__
の例外の後では、オブジェクトは通常、名前がありません(つまり、f =
部分は実行されません)ので、その参照カウントは0です。つまり、オブジェクトが正常に削除され、__del__
が呼び出されます。
>リソースを閉じる方法はコンテキストマネージャーです(別名:withステートメント)。 優れた先端。このようにオブジェクトのスコープを格納するために 'with 'を使うことができるのを知らなかった。 –
この回答は非常に明るいです。明確な説明をありがとう! –