失败的构造函数的Python析构函数

时间:2016-02-10 22:23:44

标签: python python-3.x

在Python中给出以下示例类:

class MyClass:
    def __init__(self, obj):
        self._obj = obj

    def __del__(self):
        if self._obj:
            print(self._obj)

在测试套件中,我想检查在没有参数的情况下调用构造函数时抛出异常,即:

c = MyClass()

有了这个,我从构造函数中得到了预期的异常:

Traceback (most recent call last):
  File ".../example.py", line 9, in <module>
    c = MyClass()
TypeError: __init__() missing 1 required positional argument: 'obj'

但是,析构函数也会失败并显示以下消息:

Exception ignored in: <bound method MyClass.__del__ of <__main__.MyClass object at 0x0000023D1211CD30>>
Traceback (most recent call last):
  File ".../example.py", line 6, in __del__
    if self._obj:
AttributeError: 'MyClass' object has no attribute '_obj'

据推测,这是因为缺少参数,因此永远不会调用构造函数,因此永远不会创建属性。

处理此问题的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

测试属性是否实际设置,通过使其成为类属性来提供默认值。

例如,设置class属性可使当前代码正常工作:

class MyClass:
    _obj = None  # class attribute

    def __init__(self, obj):
        self._obj = obj

    def __del__(self):
        if self._obj:
            print(self._obj)

或使用getattr()默认值:

def __del__(self):
    if getattr(self, '_obj', None):
        print(self._obj)

如果属性不存在,则返回第3个参数。

答案 1 :(得分:1)

您可以使用class-property:

class MyClass(object):
    _obj = None

    def __init__(self, obj):
        self._obj = obj

    def __del__(self):
        if self._obj:
            print(self._obj)

这样,总会有一个默认(假)值(如果实例查找失败,则类查找将成功)。

据说,python中的__del__有点像黑羊。一般来说,建议是“不要使用它”#34;出于多种原因。上下文管理器通常是一个稍微明确的替代品(尽管它们不涵盖所有用例)。