Class方法属性继承
Class method attribute inheritance
我想构建一个 class,它有一个 class 方法返回 class 的一个实例,该实例使用任何一组 pre-determined 默认值实例化,从私有 class 属性中提取。但是,我发现如果我创建一个 child class 并覆盖私有 class 属性,class 方法好像还在用parentclass的版本!为什么会这样?
这是一个演示问题的 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
.
正确。双首字母下划线破坏了属性名称,以 防止 儿童能够轻松访问它们。然而,它们 不是 ,实际上是私有的,因为 Python 中没有 "private" 这样的东西。将属性名称切换为使用单个初始下划线。
我想构建一个 class,它有一个 class 方法返回 class 的一个实例,该实例使用任何一组 pre-determined 默认值实例化,从私有 class 属性中提取。但是,我发现如果我创建一个 child class 并覆盖私有 class 属性,class 方法好像还在用parentclass的版本!为什么会这样?
这是一个演示问题的 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
.
正确。双首字母下划线破坏了属性名称,以 防止 儿童能够轻松访问它们。然而,它们 不是 ,实际上是私有的,因为 Python 中没有 "private" 这样的东西。将属性名称切换为使用单个初始下划线。