【发布时间】:2021-05-03 19:08:55
【问题描述】:
我正在尝试在特定情况下创建一个子类,但我无法为其附加属性或方法。我认为 new / init 的用法对我来说并不清楚,但我无法从互联网上找到方法。
这是一个最小的工作玩具示例,展示了我正在尝试做的事情。
---- create_special_human() 函数的编辑
# I have this
class Human():
def __init__(self):
self.introduction = "Hello I'm human"
def create_special_human():
special_human = do_very_complicated_stuffs() #returns type Human
special_human.introduction = "Hello I'm special"
return special_human
# I want to create this class
class SuperHero(Human):
def __new__(self):
special_human = create_special_human()
return special_human
def __init__(self):
self.superpower = 'fly'
def show_off(self):
print(self.introduction)
print(f"I can {self.superpower}")
human = Human()
special_human = create_special_human()
super_hero = SuperHero()
super_hero.show_off() # fails with error "type object 'Human' has no attribute 'show_off'"
print(super_hero.superpower) # fails with error "type object 'Human' has no attribute 'superpower'"
我想创建子类Superhero,我需要用create_special_human()返回的内容来初始化它,因为这个函数在实际情况下非常复杂。此外,我无法修改Human 类和create_special_human()。
我知道返回的类型是 Human,这是错误的,但我不知道为什么会这样。
【问题讨论】:
-
我认为你不能为所欲为。请参阅此answer,它解释了如果
__new__返回不同的类型,则不会调用__init__。 -
我可以通过在
__new__方法中添加superpower属性来摆脱__init__。但如果我这样做,我仍然会遇到无法识别show_off方法的问题。 -
您可以将
do_very_complicated_stuffs(self)添加到SuperHero.__init__吗?为什么使用__new__? -
@OneCricketeer 好问题,实际上在我的真实情况下我不能,让我修改我的玩具示例。我将修改 create_special_human() 以更好地匹配我的情况。
-
do_very_complicated_stuffs()恰好返回了一个Human类型的对象,但它是由多层构建的。它背后的initialHuman()初始化器被挖掘得很深。这就是为什么我不能把这段代码复制到我的__init__
标签: python python-3.x class inheritance design-patterns