强制装饰器仅在继承的类上扩展静态字段,即使未显式重写也是如此

时间:2014-10-04 21:32:09

标签: python inheritance static python-decorators

我正在编写一个用于继承类的装饰器,而装饰器应该将一些值添加到基类的字段列表中。我发现的问题是,除非该类定义明确地列出该字段,否则装饰器最终会修改基类,而这又将值添加到从该类继承的所有其他类中。似乎字段没有在类上定义,而是操纵Base类上的字段。有没有办法强制继承的类拥有自己的可变字段(以与Base字段相同的值开头)不影响Base类字段的值?

可以肯定的是,我可以通过不做我正在做的事情找到解决方法,但我想知道是否有办法让我想做的工作,最好是通过修改装饰器。除了一个解决方案,解释为什么这是和我不了解python,静态字段继承和装饰器将是伟大的!

我已经给出了以下基本情况。 请注意打印行是指如果单独使用Extension#类,而不是像显示的那样并排使用它们。

def add_values(cls):
    cls.my_list.append(1)
    return cls

class Base(object):
    my_list = []

### in the following case, the definition of Base actually changes
@add_values
class Extension1(Base):

    def append_1(self):
        self.my_list.append(1)
        print(self.my_list) ### this prints [1, 1]
        print(Base.my_list) ### this prints [1, 1]


### in this case, the definition of Base is fine and it only modifies
### the field on this class definition, which is what I'd expect.
@add_values
class Extension2(Base):
    my_list = []

    def append_1(self):
        self.my_list.append(1)
        print(self.my_list) ### this prints [1, 1]
        print(Base.my_list) ### this prints []

1 个答案:

答案 0 :(得分:2)

类不会复制它们从基类继承的值。它只是属性查找系统,用于搜索它们之前定义的位置。您应该做的是将my_list类变量的变异更改为非变异版本:

def add_values(cls):
    cls.my_list = cls.my_list + [1]  # like cls.my_list.append(1), but makes a new list
    return cls

这将创建一个添加了1的新列表,并将其绑定到add_values,无论您是装饰基类还是派生类。