파이썬 객체를 강제로 삭제하는 방법은 무엇입니까?
__del__파이썬 의 세부 사항 , 언제, 왜 사용해야하며, 사용하지 말아야할지 궁금합니다. 나는 그것이 __new__/ 와 반대가 아니라는 점에서 소멸자에게 순진하게 기대했던 것과는 다르다는 것을 어려운 방법으로 배웠다 __init__.
class Foo(object):
def __init__(self):
self.bar = None
def open(self):
if self.bar != 'open':
print 'opening the bar'
self.bar = 'open'
def close(self):
if self.bar != 'closed':
print 'closing the bar'
self.bar = 'close'
def __del__(self):
self.close()
if __name__ == '__main__':
foo = Foo()
foo.open()
del foo
import gc
gc.collect()
문서 에서 인터프리터가 종료 될 때 여전히 존재하는 객체에 대해 메서드가 호출된다는 보장 이 없다는 것을 알았습니다 __del__().
Foo인터프리터가 종료 될 때 존재하는 모든 인스턴스에 대해 막대가 닫히는 것을 어떻게 보장 할 수 있습니까?- 위의 코드 스 니펫에서 막대가 닫히
del foo거나 닫히지gc.collect()않습니까? 이러한 세부 사항을 더 세밀하게 제어하려면 (예 : 객체가 참조되지 않을 때 막대를 닫아야 함)이를 구현하는 일반적인 방법은 무엇입니까? - 이미
__del__호출 된 것은 언제__init__호출됩니까? 어떤이 경우에 대해__init__제기?
리소스를 닫는 방법은 컨텍스트 관리자입니다 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) 파이썬의 객체는 참조 횟수가 0 일 때 삭제됩니다. 귀하의 예제 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"
산출:
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) 보자 :
class Foo(object):
def __init__(self):
raise Exception
def __del__(self):
print "deling", self
if __name__ == '__main__':
f = Foo()
제공합니다 :
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__호출 됨을 의미합니다 .
일반적으로 무슨 일이 있어도 어떤 일이 일어나도록하려면
from exceptions import NameError
try:
f = open(x)
except ErrorType as e:
pass # handle the error
finally:
try:
f.close()
except NameError: pass
finally blocks will be run whether or not there is an error in the try block, and whether or not there is an error in any error handling that takes place in except blocks. If you don't handle an exception that is raised, it will still be raised after the finally block is excecuted.
The general way to make sure a file is closed is to use a "context manager".
http://docs.python.org/reference/datamodel.html#context-managers
with open(x) as f:
# do stuff
This will automatically close f.
For your question #2, bar gets closed on immediately when it's reference count reaches zero, so on del foo if there are no other references.
Objects are NOT created by __init__, they're created by __new__.
http://docs.python.org/reference/datamodel.html#object.new
When you do foo = Foo() two things are actually happening, first a new object is being created, __new__, then it is being initialized, __init__. So there is no way you could possibly call del foo before both those steps have taken place. However, if there is an error in __init__, __del__ will still be called because the object was actually already created in __new__.
Edit: Corrected when deletion happens if a reference count decreases to zero.
Perhaps you are looking for a context manager?
>>> class Foo(object):
... def __init__(self):
... self.bar = None
... def __enter__(self):
... if self.bar != 'open':
... print 'opening the bar'
... self.bar = 'open'
... def __exit__(self, type_, value, traceback):
... if self.bar != 'closed':
... print 'closing the bar', type_, value, traceback
... self.bar = 'close'
...
>>>
>>> with Foo() as f:
... # oh no something crashes the program
... sys.exit(0)
...
opening the bar
closing the bar <type 'exceptions.SystemExit'> 0 <traceback object at 0xb7720cfc>
- Add an exit handler that closes all the bars.
__del__()gets called when the number of references to an object hits 0 while the VM is still running. This may be caused by the GC.- If
__init__()raises an exception then the object is assumed to be incomplete and__del__()won't be invoked.
참고URL : https://stackoverflow.com/questions/6772481/how-to-force-deletion-of-a-python-object
'Program Club' 카테고리의 다른 글
| 다른 사람의 저장소를 GitHub의 Git 하위 모듈로 사용 (0) | 2020.12.01 |
|---|---|
| CMakeLists.txt에서 LDFLAGS를 설정하는 방법은 무엇입니까? (0) | 2020.12.01 |
| tar에서 다른 디렉토리로 단일 파일을 추출하는 방법은 무엇입니까? (0) | 2020.12.01 |
| y 축 matplotlib에서만 마이너 틱을 켜는 방법 (0) | 2020.12.01 |
| [=]는 모든 지역 변수가 복사된다는 것을 의미합니까? (0) | 2020.12.01 |