假设在运行时有一个程序包含几个对象.
程序结束时是否调用每个对象的__del__方法?
如果是,我可以举例如下:
class Client:
__del__( self ):
disconnect_from_server()
Run Code Online (Sandbox Code Playgroud)
有许多潜在的困难与使用相关__del__.通常,没有必要,或者最好自己定义它.
相反,如果您想要一个在退出或异常后自行清理的对象,请使用上下文管理器:
根据卡尔的评论:
class Client:
def __exit__(self,ext_type,exc_value,traceback):
self.disconnect_from_server()
with Client() as c:
...
Run Code Online (Sandbox Code Playgroud)
原始答案:
import contextlib
class Client:
...
@contextlib.contextmanager
def make_client():
c=Client()
yield c
c.disconnect_from_server()
with make_client() as c:
...
Run Code Online (Sandbox Code Playgroud)
我的第二个概念是使用上下文管理器和with语句而不是依赖__del__(出于同样的原因,人们更喜欢尝试/最终使用Java中的终结器方法,加上一个:在Python中,__del__方法的存在可以使循环垃圾无法收集).
但是,鉴于目标是"退出或异常后自行清理的对象",@ ~unutbu的实现是不正确的:
@contextlib.contextmanager
def make_client():
c=Client()
yield c
c.disconnect_from_server()
with make_client() as c:
...
Run Code Online (Sandbox Code Playgroud)
如果在...部件中引发异常,disconnect_from_server_则不会被调用(因为异常传播通过make_client,在那里未被捕获,因此在它等待时终止它yield).
修复很简单:
@contextlib.contextmanager
def make_client():
c=Client()
try: yield c
finally: c.disconnect_from_server()
Run Code Online (Sandbox Code Playgroud)
从本质上讲,该with语句几乎可以让你忘记好的旧的try/finally语句... 除非你在编写上下文管理器时contextlib,然后记住它真的很重要! - )