【发布时间】:2017-03-25 00:36:35
【问题描述】:
我已经搜索过,但找不到任何充分的理由使用 python 的 __enter__ /__exit__ 而不是 __init__ (或 __new__ ?) / __del__ 。
我了解__enter__ / __exit__ 旨在与with 语句一起用作上下文管理器,with 语句非常棒。但与之对应的是,这些块中的任何代码仅在该上下文中执行。通过使用这些而不是__init__ / __del__,我似乎正在与调用者创建一个隐式合约,他们必须使用with,但是没有办法强制执行这样的合约,并且该合约只能通过文档(或阅读代码)。这似乎是个坏主意。
我似乎在 with 块内使用 __init__ / __del__ 获得了相同的效果。但是通过使用它们而不是上下文管理方法,我的对象在其他场景中也很有用。
那么任何人都可以想出一个令人信服的理由来说明我曾经想要使用上下文管理方法而不是构造函数/析构函数方法吗?
如果有更好的地方问这样的问题,请告诉我,但似乎没有太多关于此的好信息。
跟进:
这个问题是基于一个错误(但可能很常见)的假设,因为我总是使用with 来实例化一个新对象,在这种情况下__init__/__del__ 非常接近与__enter__/__exit__ 相同的行为(除了您无法控制何时或是否执行__del__ 之外,这取决于垃圾收集,如果进程首先终止,它可能永远不会被调用)。但如果你在with 语句中使用预先存在的对象,它们当然就完全不同了。
【问题讨论】:
-
何时(甚至是否)
__del__被调用是不确定的。依靠__del__进行清理可能会丢失数据。
标签: python constructor destructor with-statement contextmanager