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
不会覆盖class
Human
上设置的默认值,而只是在引用为
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
不会覆盖class
Human
上设置的默认值,而只是在引用为
self.\u fingers
时将其隐藏

当变量引用可变类型(如列表)时,会有点麻烦。您必须小心不要对默认值执行会修改它的操作,尽管执行
self.name=value
仍然是安全的


这种方法的优点在于,与其他方法相比,它往往会导致更少的代码行,这通常是一件好事(tm)。

请注意,如果所有子类实现都调用超类实现,则可以忽略它们<代码>B(A)级:及格就行了。您是在寻找类属性还是常规实例属性?你能给出一个不那么抽象的例子吗?取决于字段
\u f
是指可变的还是不可变的类型。
\u f
应该是类字段还是实例字段?它应该是实例字段,应该是mutable@jonrsharpe我真的很惊讶,正如我读过这篇文章:我甚至认为我不应该尝试它(一个未来的教训)。谢谢。请注意,如果所有的子类实现都是调用超类实现,那么您可以忽略它们<代码>B(A)级:及格就行了。您是在寻找类属性还是常规实例属性?你能给出一个不那么抽象的例子吗?取决于字段
\u f
是指可变的还是不可变的类型。
\u f
应该是类字段还是实例字段?它应该是实例字段,应该是mutable@jonrsharpe我真的很惊讶,正如我读过这篇文章:我甚至认为我不应该尝试它(一个未来的教训)。谢谢