0

我有一个 python 类,作为进一步子类的基类。它包含一个应该作用于所有子类的方法,例如我想把它放在基类中。问题是,这个方法应该返回子类的一个新实例。但是我由于基类位于子类的定义之前,我不能创建子类的新实例,因为它在基类的范围内是不知道的:

class Base:
  def __init__(self, value):
    self.value = value

  def convert_child_classes(self, newclass):
    newvalue = MakeUsableInNewclass(self.value)
    newattr = MakeUsableInNewclass(self.subclassattr)
    return newclass(newattr, newvalue)


class Child1(Base):
  def __init__(self, subclassattr, value)
    super(Child, self).__init__(value)
    self.subclassattr = subclassattr

  def MethodForSubClassAttr(self):
    ...do sth with self.subclassattr...


class Child2(Base):
  def __init__(self, subclassattr, value)
    super(Child, self).__init__(value)
    self.subclassattr = subclassattr

  def SomeOtherSubClassAttrMethod(self):
    ...do sth that is related to this class attr...

如果我有 Child1 的实例,我希望能够对其数据做一些事情,然后在调用 convert_child_classes(Child2) 时返回具有新值的 Child2 的实例:

A = Child1('someattr', 5)
B = A.convert_child_classes(Child2)

现在 B 应该是 Child2 的一个实例,其值是从 Child1 计算出来的。但是由于 Base 类现在知道 Child1 或 Child2 是什么,它不能启动新类。

4

2 回答 2

1

像这样的东西应该可以工作(未经测试):

class Measurement:

    @classmethod
    def from_other(cls, other):
        base = other.convert_to_base_unit()
        converted = cls.base_to_unit(base)
        return cls(converted)

    @classmethod
    def base_to_unit(cls, value):
        # Let the subclass implement this
        raise NotImplementedError

    def convert_to_base_unit(self):
        # Let the subclass implement this
        raise NotImplementedError

以这种方式实现,基类不需要知道任何关于子类的信息。基类提供模板方法 ( from_other),子类提供实现。

于 2018-12-08T12:28:43.517 回答
1

我得到了你的问题:
1. 实际上你使用的是Childinsuper并且它是错误的,因为它应该是你正在操作的类的名称,在这种情况下Child1Child2.
2.我将 Base 添加为一个抽象类,以确保它不会被实例化(正如我从你的问题中得到的那样)。
3. 由于该方法MakeUsableInNewClass是强制实施的,我会添加一个abstractmethod以确保在子类上实施。

所以正确的代码是:

from abc import ABC, abstractmethod
class Base(ABC):
    def __init__(self, value):
        self.value = value

    def convert_child_classes(self, newclass):
        newvalue, newattr = self.MakeUsableInNewclass()
        return newclass(newattr, newvalue)

    @abstractmethod
    def MakeUsableInNewclass(): pass

class Child1(Base):
    def __init__(self, subclassattr, value):
        super(Child1, self).__init__(value)
        self.subclassattr = subclassattr

    def MakeUsableInNewclass(self):
        newvalue = self.value #do operations
        newattr = self.subclassattr #do operations
        return newvalue, newattr

class Child2(Base):
    def __init__(self, subclassattr, value):
        super(Child2, self).__init__(value)
        self.subclassattr = subclassattr

    def MakeUsableInNewclass(self):
        newvalue = self.value #do operations
        newattr = self.subclassattr #do operations
        return newvalue, newattr
于 2018-12-08T12:32:18.267 回答