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静态方法。如果你想要这些,请参阅本节。”