繁体   English   中英

强制python子类init使用子类变量,而不是父类

[英]Force python subclass init to use subclass variables, not parent class

在以下代码中:

class A(object):
  VALUE = 1
  def __init__(self, value=VALUE):
    self.value = value

class B(A):
  VALUE = 2

我希望B()。值应该等于2,但是:

B().value = 1

是否有一种优雅的方法来定义一个类层次结构,其中子类只能声明它们想要覆盖的类变量并使它们成为实例变量的默认值? 我仍然希望允许在每个实例级别更改这些,例如。

b = B(value=3)

这是另一个默认参数问题。 关键是你写的时候

def foo(value=VALUE):

函数内部的代码被编译并成为一个函数对象。 就在这个时候 - 而不是在通话时间! - 存储默认参数。 因此,当您定义B ,为时已晚: foo的默认值已经设置,更改VALUE将不会产生任何影响。

如果这看起来很奇怪,假设foo是一个全局函数:

default = 3
def foo(x=default): pass

然后任何其他代码,任何地方,可以搞砸了foo

global default
default = 4

这可以说是令人困惑的。


要强制在运行时完成查找而不是编译时间,您需要将它们放在函数中:

def foo(value=None):
    self.value = self.VALUE if value is None else value

或(不完全相同但更漂亮)

self.value = value or self.VALUE

(这是不同的,因为它将任何 'falsy'值视为哨兵 - 即0[]{}等都将被VALUE覆盖。)


编辑:@mgilson指出了另一种方法:

def foo(**kwargs):
    self.value = kwargs.get("value", self.VALUE)

这更简洁,因为它不需要你创建一个sentinel值(如Noneobject() ,但它确实从根本上改变了foo的参数规范,因为现在它将接受任意关键字参数。你的调用。

不应在func声明行中定义默认值,否则,当python读取此行时,默认值将被聚焦,无论您稍后更改VALUE,默认值都不会更改。

您可以按如下方式编写它:

class A:
    VALUE = 1
    def __init__(self, value=None):
        if value is None:
            value = self.VALUE
        self.value = value

class B(A):
    VALUE = 2

print(A().value)
print(B().value)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM