Python 类的所有子类中的字段
假设我们有一个类Python 类的所有子类中的字段,python,inheritance,Python,Inheritance,假设我们有一个类a,一个继承自a的类B,还有继承自B的类C,D和E 我们希望所有这些类都有一个用默认值初始化的属性\u f,并且我们希望该属性是可变的,并且对于类的每个实例都有一个单独的值,即它不应该是所有子类使用的a的静态常量值 一种方法是在A的\uuu init\uuu方法中定义\u f,然后在子类中依赖此方法: class A: def __init__(self): self._f = 'default_value' class B(A): def __
a
,一个继承自a
的类B
,还有继承自B
的类C
,D
和E
我们希望所有这些类都有一个用默认值初始化的属性\u f
,并且我们希望该属性是可变的,并且对于类的每个实例都有一个单独的值,即它不应该是所有子类使用的a
的静态常量值
一种方法是在A的\uuu init\uuu
方法中定义\u f
,然后在子类中依赖此方法:
class A:
def __init__(self):
self._f = 'default_value'
class B(A):
def __init__(self):
super(B, self).__init__()
class C(B):
def __init__(self):
super(C, self).__init__()
有没有什么好的python方法可以避免这种情况,并且可能避免使用元类?如果您的目标是通过消除调用基类构造函数来简化子类构造函数,但仍然能够覆盖子类中的默认值,有一种常见的范例可以利用这样一个事实:如果实例上不存在属性,Python将返回该属性的类值 使用一个更具体的例子,而不是做
class Human(object):
def __init__(self):
self._fingers = 10
def __repr__(self):
return 'I am a %s with %d fingers' % (self.__class__.__name__, self._fingers)
class MutatedHuman(Human):
def __init__(self, fingers):
super(MutatedHuman, self).__init__()
self._fingers = fingers
print MutatedHuman(fingers=11)
print Human()
…你可以用
class Human(object):
_fingers = 10
def __repr__(self):
return 'I am a %s with %d fingers' % (self.__class__.__name__, self._fingers)
class MutatedHuman(Human):
def __init__(self, fingers):
self._fingers = fingers
print MutatedHuman(fingers=11)
print Human()
…这两个输出
I am a MutatedHuman with 11 fingers
I am a Human with 10 fingers
重要的一点是,第二个示例中的行self.\u fingers=fingers
不会覆盖classHuman
上设置的默认值,而只是在引用为self.\u fingers
时将其隐藏
当变量引用可变类型(如列表)时,会有点麻烦。您必须小心不要对默认值执行会修改它的操作,尽管执行self.name=value
仍然是安全的
这种方法的优点在于,与其他方法相比,它往往会产生更少的代码行,这通常是一件好事(tm)。如果您的目标是通过消除调用基类构造函数来简化子类构造函数,但仍然能够覆盖子类中的默认值,有一种常见的范例可以利用这样一个事实:如果实例上不存在属性,Python将返回该属性的类值 使用一个更具体的例子,而不是做
class Human(object):
def __init__(self):
self._fingers = 10
def __repr__(self):
return 'I am a %s with %d fingers' % (self.__class__.__name__, self._fingers)
class MutatedHuman(Human):
def __init__(self, fingers):
super(MutatedHuman, self).__init__()
self._fingers = fingers
print MutatedHuman(fingers=11)
print Human()
…你可以用
class Human(object):
_fingers = 10
def __repr__(self):
return 'I am a %s with %d fingers' % (self.__class__.__name__, self._fingers)
class MutatedHuman(Human):
def __init__(self, fingers):
self._fingers = fingers
print MutatedHuman(fingers=11)
print Human()
…这两个输出
I am a MutatedHuman with 11 fingers
I am a Human with 10 fingers
重要的一点是,第二个示例中的行self.\u fingers=fingers
不会覆盖classHuman
上设置的默认值,而只是在引用为self.\u fingers
时将其隐藏
当变量引用可变类型(如列表)时,会有点麻烦。您必须小心不要对默认值执行会修改它的操作,尽管执行self.name=value
仍然是安全的
这种方法的优点在于,与其他方法相比,它往往会导致更少的代码行,这通常是一件好事(tm)。请注意,如果所有子类实现都调用超类实现,则可以忽略它们<代码>B(A)级:及格就行了。您是在寻找类属性还是常规实例属性?你能给出一个不那么抽象的例子吗?取决于字段
\u f
是指可变的还是不可变的类型。\u f
应该是类字段还是实例字段?它应该是实例字段,应该是mutable@jonrsharpe我真的很惊讶,正如我读过这篇文章:我甚至认为我不应该尝试它(一个未来的教训)。谢谢。请注意,如果所有的子类实现都是调用超类实现,那么您可以忽略它们<代码>B(A)级:及格就行了。您是在寻找类属性还是常规实例属性?你能给出一个不那么抽象的例子吗?取决于字段\u f
是指可变的还是不可变的类型。\u f
应该是类字段还是实例字段?它应该是实例字段,应该是mutable@jonrsharpe我真的很惊讶,正如我读过这篇文章:我甚至认为我不应该尝试它(一个未来的教训)。谢谢