class Package:
def __init__(self):
self.files = []
# ...
def __del__(self):
for file in self.files:
os.unlink(file)
__del__(self)失败,并出现AttributeError异常。 我了解在调用__del__()时, Python不保证 “全局变量”(在这种情况下是否存在成员数据__del__()存在。 如果是这种情况,并且这是导致异常的原因,那么如何确保对象正确销毁?
#1楼
我认为问题可能出在__init__如果代码多于所示?
即使未正确执行__init__或引发异常,也会调用__del__ 。
#2楼
@contextlib.contextmanager
def packageResource():
class Package:
...
package = Package()
yield package
package.cleanup()
另外,尽管可能不如Pythonic,但是您可以覆盖Package.__new__ :
class Package(object):
def __new__(cls, *args, **kwargs):
@contextlib.contextmanager
def packageResource():
# adapt arguments if superclass takes some!
package = super(Package, cls).__new__(cls)
package.__init__(*args, **kwargs)
yield package
package.cleanup()
def __init__(self, *args, **kwargs):
...
并with Package(...) as package 。
为了contextlib.closing ,请将您的清理函数命名为close并使用contextlib.closing ,在这种情况下,您可以通过with contextlib.closing(Package(...))使用未修改的Package类,也可以将其__new__重写为更简单的方法
class Package(object):
def __new__(cls, *args, **kwargs):
package = super(Package, cls).__new__(cls)
package.__init__(*args, **kwargs)
return contextlib.closing(package)
而且此构造函数是继承的,因此您可以简单地继承,例如
class SubPackage(Package):
def close(self):
pass
#3楼
# package.py
import atexit
import os
class Package:
def __init__(self):
self.files = []
atexit.register(self.cleanup)
def cleanup(self):
print("Running cleanup...")
for file in self.files:
print("Unlinking file: {}".format(file))
# os.unlink(file)
但是,请记住,这将保留所有创建的Package实例,直到终止Python。
使用上面的代码的演示保存为package.py :
$ python
>>> from package import *
>>> p = Package()
>>> q = Package()
>>> q.files = ['a', 'b', 'c']
>>> quit()
Running cleanup...
Unlinking file: a
Unlinking file: b
Unlinking file: c
Running cleanup...
#4楼
#5楼
这是一个最小的工作框架:
class SkeletonFixture:
def __init__(self):
pass
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
pass
def method(self):
pass
with SkeletonFixture() as fixture:
fixture.method()
重要提示: 返回自我
如果您像我一样,却忽略了return self部分( 克林特·米勒的正确答案的一部分 ),那么您将盯着这个废话:
Traceback (most recent call last):
File "tests/simplestpossible.py", line 17, in
fixture.method()
AttributeError: 'NoneType' object has no attribute 'method'
我花了半天时间。 希望它能帮助下一个人。