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

Python 继承虚拟类方法-如何从基类调用它?,python,inheritance,class-method,Python,Inheritance,Class Method,让B继承自A。假设B的某些行为依赖于类属性cls_x,我们希望在构建B对象时设置此依赖关系。由于它不是一个简单的操作,我们希望将其包装在一个类方法中,构造函数将调用该类方法。例如: B(A)类: cls_x='B' @类方法 def cm(cls): 返回cls.cls\u x 定义初始化(自): self.attr=B.cm() 问题:cm以及\uuuuu init\uuuu将始终执行相同的操作,并且它们的行为在每个派生类中必须保持不变。因此,我们希望将它们都放在基类中,而不是在任何派生类中

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

B(A)类:
cls_x='B'
@类方法
def cm(cls):
返回cls.cls\u x
定义初始化(自):
self.attr=B.cm()
问题:
cm
以及
\uuuuu init\uuuu
将始终执行相同的操作,并且它们的行为在每个派生类中必须保持不变。因此,我们希望将它们都放在基类中,而不是在任何派生类中定义它。唯一的区别是调用
cm
——无论是
A
还是
B
(或者是
B1
B2
,每一个都继承自
A
),无论构造什么。所以我们想要的是这样的:

A类:
cls_x='A'
@类方法
def cm(cls):
返回cls.cls\u x
定义初始化(自):
self.attr=classofwhatevisinstated.cm()#如何执行此操作?
B(A)类:
cls_x='B'
我觉得这要么是Python的继承机制中我缺少的一些非常简单的东西,要么整个问题应该以完全不同的方式处理


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

对于安装的
类,您可以使用
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的实例化过程中调用
\uu init\uuu()
时,它是在类B的上下文中调用的,而类B是
self
引用的。

这样看:您的问题本质上是“如何获取实例的类?”。该问题的答案是使用以下函数:

ClassOfWhateverIsInstantiated = type(self)
但您甚至不需要这样做,因为可以通过实例直接调用classmethods:

def __init__(self):
    self.attr = self.cm()  # just use `self`
这是因为classmethods会自动为您查找实例的类。发件人:

[classmethod]可以在类(例如
C.f()
)或实例上调用 (例如
C().f()
)。实例被忽略,但其类除外


这是可行的,但我想知道为什么。这是否意味着
self
绑定到对象及其类,这取决于请求的内容(classmethod或normal)?B继承A的方法。想象一下
\uuuu init\uuuu
方法是在B中定义的。我理解这一点。我感到困惑的是,我可以同时使用classmethods作为
B.cm()
B.cm()
,而
self
将自动为我解析,这是@Aran Fey在他们的回答中解释的。哦,我明白了。是的,
b.cm()
b.cm()
之间没有区别,我应该早点看到这个链接。对于一个C/C++背景的程序员来说,下面的方法非常有启发性:“类方法不同于C++或java静态方法。如果你想要这些,请参阅本节。”