类方法属性inheritan

2024-04-23 10:48:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我想构建一个类,它有一个class方法返回一个实例,这个实例是用一组预先确定的默认值实例化的,从私有类属性中提取的。然而,我发现,如果我创建一个私有类属性被覆盖的子类,class方法似乎仍然使用父类的版本!为什么会这样?你知道吗

以下是一个MWE演示的问题:

class MyCoolBeansClass:

    __MyCoolBeansPrivateAttr = {'FizzBuzz': {'foo': 'Fizz', 'bar': 'Buzz'},
                                 'WimWam': {'foo': 'Wim', 'bar': 'Wam'}}

    def __init__(self, foo, bar):
        self.foo = foo
        self.bar = bar

    def __str__(self):
        return 'foo: {foo}\tbar: {bar}'.format(foo=self.foo, bar=self.bar)

    @classmethod
    def specificBeanz(cls, cbtype, printclass=False):
        """ Create a specific instance from a pre-determined set of instances """
        if printclass:
            print("Class Name: " + cls.__name__)

        if cbtype not in cls.__MyCoolBeansPrivateAttr.keys():
            raise ValueError('Invalid pre-determined Beanz, valid values are: ' + 
                             ', '.join(cls.__MyCoolBeansPrivateAttr.keys()))

        kwargs = cls.__MyCoolBeansPrivateAttr[cbtype]
        return cls(**kwargs)

class MyCubeGleamer(MyCoolBeansClass):
    __MyCoolBeansPrivateAttr = {'GleamCube': {'foo': 'Gleam', 'bar': 'Cube'},
                                'FogSnarl': {'foo': 'Fog', 'bar': 'Snarl'}}

if __name__ == "__main__":
    FizzBuzz = MyCoolBeansClass.specificBeanz('FizzBuzz', printclass=True)
    print(FizzBuzz)

    WimWam = MyCoolBeansClass.specificBeanz('WimWam', printclass=True)
    print(WimWam)

    GleamCube = MyCubeGleamer.specificBeanz('GleamCube', printclass=True)
    print(GleamCube)

运行此命令可以:

> testinheritance.py
Class Name: MyCoolBeansClass
foo: Fizz       bar: Buzz
Class Name: MyCoolBeansClass
foo: Wim        bar: Wam
Class Name: MyCubeGleamer
-----------------------------------------------------------------------------
Traceback (most recent call last):
  File "testinheritance.py", line 37, in <module>
    GleamCube = MyCubeGleamer.specificBeanz('GleamCube', printclass=True)
  File "testinheritance.py", line 21, in specificBeanz
    ', '.join(cls.__MyCoolBeansPrivateAttr.keys()))
ValueError: Invalid pre-determined Beanz, valid values are: FizzBuzz, WimWam
-----------------------------------------------------------------------------

如您所见,在MyCubeGleamer.specificBeanz()调用中,cls.__name__似乎工作正常,但cls.__MyCoolBeansPrivateAttr正在检索MyCoolBeansClass.__MyCoolBeansPrivateAttr。你知道吗


Tags: selffoobarclassclsprintfizzbuzzprintclass
1条回答
网友
1楼 · 发布于 2024-04-23 10:48:28

正确。双首字母下划线会损坏属性名称,以防止子级能够轻松访问它们。它们不是私有的,但是实际上是私有的,因为Python中没有“私有”这个词。将属性名称切换为使用单个初始下划线。你知道吗

相关问题 更多 >