通过继承的静态方法更改不可变类型类属性

时间:2015-02-15 18:58:20

标签: python inheritance

我是Python的新手,也是OOP的新手。我有一个派生类,它从基类继承了几个类属性,其中一些是可变类型,而另一些是不可变的。派生类还继承了一个静态方法,该方法将类属性重置为其原始值。

这在基类中工作正常,并且在涉及可变类型类属性的派生类中不是问题。问题出现在不可改变的问题上。我知道无论如何我可能不得不完全重新设计它,但它确实提出了一个关于继承的问题,我找不到满意的答案。

以下是上述问题的简化说明:

class Parent(object):
    boolean_attribute = True
    list_attribute = ['1', '2', '3']


    @staticmethod
    def static_reset():
        Parent.boolean_attribute = True
        Parent.list_attribute = ['1', '2', '3']



class Child(Parent):
    pass

print(Parent.list_attribute)
Parent.list_attribute.remove('1')
print(Parent.list_attribute)
Parent.static_reset()
print(Parent.list_attribute)

print(Parent.boolean_attribute)
Parent.boolean_attribute = False
print(Parent.boolean_attribute)
Parent.static_reset()
print(Parent.boolean_attribute)

print(Child.list_attribute)
Child.list_attribute.remove('1')
print(Child.list_attribute)
Child.static_reset()
print(Child.list_attribute)

print(Child.boolean_attribute)
Child.boolean_attribute = False
print(Child.boolean_attribute)
Child.static_reset()
print(Child.boolean_attribute)

以上输出如下:

['1', '2', '3']
['2', '3']
['1', '2', '3']
True
False
True
['1', '2', '3']
['2', '3']
['1', '2', '3']
True
False
False

请注意,static_reset方法在最后一种情况下没有工作。

对此处发生的事情的任何见解都将非常感激。

1 个答案:

答案 0 :(得分:0)

获取属性,并且该属性不存在时,将查询整个类层次结构。这就是继承在Python中的工作原理。

但是当设置属性时,它直接在对象(实例或类)上完成。这就是压倒一切的方式。

您已设置Child.boolean_attribute属性,之前它不存在。这与变异 list_attribute引用的列表不同;你永远不会设置那个属性。 Child.list_attribute只有获取属性,之后您在列表对象(不是list.remove()Child)上使用Parent方法来更改内容。

如果您实际设置list_attribute

,您会看到相同的行为
Child.list_attribute = ['foo', 'bar']

使用vars() function

时,您会发现这种情况
>>> class Parent(object):
...     boolean_attribute = True
...     list_attribute = ['1', '2', '3']
... 
>>> class Child(Parent):
...     pass
... 
>>> vars(Child)
dict_proxy({'__module__': '__main__', '__doc__': None})
>>> vars(Parent)
dict_proxy({'boolean_attribute': True, '__module__': '__main__', 'list_attribute': ['1', '2', '3'], '__dict__': <attribute '__dict__' of 'Parent' objects>, '__weakref__': <attribute '__weakref__' of 'Parent' objects>, '__doc__': None})
>>> Child.boolean_attribute = False
>>> vars(Child)
dict_proxy({'boolean_attribute': False, '__module__': '__main__', '__doc__': None})

请注意Child现在也有boolean_attribute条目。