继承虚拟类方法 - 如何从基类中调用它?

时间:2018-05-29 10:23:17

标签: python inheritance class-method

B继承自A。假设某些B的行为取决于类属性cls_x,我们希望在构造B对象期间设置此依赖关系。由于它不是一个简单的操作,我们希望将它包装在构造函数将调用的类方法中。例如:

class B(A):
  cls_x = 'B'

  @classmethod
  def cm(cls):
    return cls.cls_x

  def __init__(self):
    self.attr = B.cm()

问题:cm以及__init__将始终执行相同的操作,并且它们的行为必须在每个派生类中保持不变。因此,我们希望将它们都放在基类中,并且在任何派生类中定义它。唯一的区别是cm的来电者 - AB(或任何B1B2,每个都来自A ),无论正在建造什么。所以我们想拥有的是这样的:

class A:
  cls_x = 'A'

  @classmethod
  def cm(cls):
    return cls.cls_x

  def __init__(self):
    self.attr = ClassOfWhateverIsInstantiated.cm()  #how to do this?

class B(A):
  cls_x = 'B'

我觉得这是一个非常简单的事情,我缺少关于Python的继承机制,或者整个问题应该完全不同地处理。

这与this问题不同,因为我不想覆盖类方法,而是完全将其实现移到基类。

2 个答案:

答案 0 :(得分:1)

对于ClassOfWhateverIsInstantiated,您可以使用self

class A:
  cls_x = 'A'

  @classmethod
  def cm(cls):
    return cls.cls_x

  def __init__(self):
    self.attr = self.cm()  # 'self' refers to B, if called from B

class B(A):
  cls_x = 'B'

a = A()
print(a.cls_x) # = 'A'
print(A.cls_x) # = 'A'

b = B()
print(b.cls_x) # = 'B'
print(B.cls_x) # = 'B'

要理解这一点,请记住,B类继承了A类的方法。所以当在B实例化期间调用__init__()时,它会在B类的上下文中被调用, self指的是哪个。

答案 1 :(得分:1)

以这种方式看待它:你的问题基本上是“如何获得实例的类?”。该问题的答案是使用type函数:

your_command | awk 'match($0,/[0-9]+\.[0-9]+\-[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/){print substr($0,RSTART,RLENGTH)}'

但你甚至不需要这样做,因为可以通过实例直接调用classmethod:

ClassOfWhateverIsInstantiated = type(self)

这是有效的,因为classmethods会自动为您查找实例的类。来自the docs

  

[classmethod]可以在类(例如def __init__(self): self.attr = self.cm() # just use `self` )或实例上调用   (例如C.f())。除了类之外,该实例将被忽略。