通过父类对象创建子类对象 [python]
在Python中,有没有办法通过父类对象来创建子类对象呢?我需要解析一个文件,所以我得:
- 打开文件并解析,得到一个父类对象
- 如果条件合适,就尝试扩展这个文件,得到一个子类对象
在检查之前必须先创建父类对象,而我已经有一个潜在的子类对象(不需要再解析文件了)
例如:
class SupClass():
def __init__(self, filename: str):
self.file = filename
class SubClass(SupClass):
def __init__(self, filename: str, extra: str):
super().__init__(filename)
self.extra = extra
但是我该怎么做类似这样的事情呢:
A = SupClass('filepath')
B = SubClass(A, 'extra_input')
谢谢你。
3 个回答
-1
你可以为额外的参数设置一个默认值:
class SubClass(SupClass):
def __init__(self, filename: str, extra: str = None):
super().__init__(filename)
self.extra = extra
1
用类的方法来处理这个问题会更好。__init__
方法应该是初始化你的类的“最简单”方式;一些额外的逻辑(比如从其他地方提取文件名)应该交给其他地方去处理。
class SubClass(SupClass):
def __init__(self, filename: str, extra: str):
super().__init__(str)
self.extra = extra
@classmethod
def from_sup_class(cls, x: SupClass, extra: str):
return cls(x.filename, extra)
A = SupClass('filepath')
B = SubClass.from_sup_class(A, 'extra')
另外,和每个子类都要重复写一个适合自己额外参数的方法相比,父类可以提供一个方法,接受任意参数,并把这些参数传递给子类。
class SupClass():
def __init__(self, filename: str):
self.file = filename
@classmethod
def from_sup_class(cls, x: SupClass, *args, **kwargs):
return cls(x.filename, *args, **kwargs)
class SubClass(SupClass):
def __init__(self, filename: str, extra: str):
super().__init__(filename)
self.extra = extra
A = SupClass('filepath')
B = SubClass.from_sub_class(A, 'extra')
从调用者的角度来看,这两种方式没有区别;子类调用的继承类方法仍然会把子类作为第一个参数传递。
无论哪种情况,你可能都不想在每个子类中重复定义 filename
参数。可以参考这个建议:https://rhettinger.wordpress.com/2011/05/26/super-considered-super/:
class SupClass:
def __init__(self, *, filename: str, **kwargs):
super().__init__(**kwargs)
self.filename = filename
@classmethod
def from_sup_class(cls, x: 'SupClass', *args, **kwargs):
return cls(filename=x.filename, *args, **kwargs)
class SubClass(SupClass):
def __init__(self, *, extra: str, **kwargs):
super().__init__(**kwargs)
self.extra = extra
A = SupClass(filename='filename')
B = SubClass.from_sup_class(A, extra='extra')
1
你可以修改子类的构造函数,让它接受一个父类的实例,并从中提取所需的信息。
class SupClass:
def __init__(self, filename: str):
self.file = filename
class SubClass(SupClass):
def __init__(self, super_instance: SupClass, extra: str):
super().__init__(super_instance.file)
self.extra = extra
A = SupClass('filepath')
B = SubClass(A, 'extra_input')