当我尝试根据参数尝试获取超类(父类)的实例时,我想获取子类之一的实例。例如,我有一个父类(我正在使用python3):
class Man:
def __init__(self, name, age):
self.name = name
self.age = age
def say_hello(self):
print("Hello! My name is {}.".format(self.name))
和子类:
class YoungMan(Man):
def say_hello(self):
print("Hey, man! Wazap?")
如果男人的年龄小于30岁,我希望它成为年轻人:
John = Man('John', 25)
type(John) #<class '__main__.YoungMan'>
John.say_hello() #Hey, man! Wazap?
我尝试用Man.__new__()
解决它:
class Man:
def __new__(cls, name, age):
if age < 30:
return YoungMan(name, age)
else:
return super(Man, cls).__new__()
...
但是John.say_hello()
返回Hello! My name is John.
,因此Man
方法覆盖了YoungMan
方法。在我尝试对Man
使用元类之后:
class ManFactory(type):
def __call__(self, name, age):
if age < 30:
return YoungMan(name, age)
class Man(metaclass=ManFactory):
...
但是它在ManFactory.__call__()
上运行。
我知道我可以使用函数John = get_Man(name, age)
来返回正确的类,但是它并不那么帅。我的问题是关于这样的事情:
John = Man('John', 25)
type(John) #<class '__main__.YoungMan'>
John.say_hello() #Hey, man! Wazap?
Brad = Man('Brad', 54)
type(Brad) #<class '__main__.Man'>
Brad.say_hello() #Hello! My name is Brad.
答案 0 :(得分:3)
不确定这是否是一种好的做法,但您可以设置self.__class__
:
class Man:
def __init__(self, name, age):
if age < 30: self.__class__ = YoungMan
self.name = name
self.age = age
def say_hello(self):
print("Hello! My name is {}.".format(self.name))
class YoungMan(Man):
def say_hello(self):
print("Hey, man! Wazap?")
a = Man("Brad", 15)
print(type(a))
>>><class '__main__.YoungMan'>
a.say_hello()
>>>Hey, man! Wazap?
此方法的主要问题是YoungMan仍将由Man.__init__()
构造,因此这些类必须兼容。创建函数get_man()
仍然是最佳解决方案。