通过父类对象创建子类对象 [python]

0 投票
3 回答
63 浏览
提问于 2025-04-14 17:22

在Python中,有没有办法通过父类对象来创建子类对象呢?我需要解析一个文件,所以我得:

  1. 打开文件并解析,得到一个父类对象
  2. 如果条件合适,就尝试扩展这个文件,得到一个子类对象

在检查之前必须先创建父类对象,而我已经有一个潜在的子类对象(不需要再解析文件了)

例如:

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')

撰写回答