python - 调用父类时返回子类
问题描述
在尝试根据参数获取超类(父类)的实例时,我想获取其中一个子类的实例。例如,我有父类(我正在使用 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?")
如果 Man 的年龄小于 30,我希望它成为 YoungMan:
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.
SoMan
方法会覆盖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.
解决方案
不确定这是否是好的做法,但您可以设置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()
仍然是最好的解决方案。
推荐阅读
- c++ - 保留向量段错误
- omnet++ - 如何在静脉版本 5 中将车辆的节点 ID、方向和速度存储在 RSU 中?
- javascript - Сheck 对象字段以查找与本机 javascript 上的指定条件匹配的数据
- xml - XPATH:将根节点添加到节点集
- php - 如何将从用户收到的数据传输到json
- sql - 根据日期标准增加价值
- django - 在不同应用程序中的视图之间重定向()
- angular - mat-card click 没有得到复选框的值
- c++ - 用k个顶点CGAL c ++创建面
- ios - 无法在此文件中预览 - 活动方案不会构建此文件:CatalinaOS 中 Xcode 11 上的 SwiftUI