继承虚拟 class 方法 - 如何从基础 class 调用它?
Inheriting a virtual class method - how to call it from base class?
让B
继承自A
。假设 B
的某些行为依赖于 class 属性 cls_x
并且我们希望在构造 B
对象期间设置这种依赖性。由于这不是一个简单的操作,我们希望将其包装在构造函数将调用的 class 方法中。示例:
class B(A):
cls_x = 'B'
@classmethod
def cm(cls):
return cls.cls_x
def __init__(self):
self.attr = B.cm()
问题:cm
和 __init__
将始终做相同的事情,并且它们的行为必须在每个派生的 class 中保持相同。因此,我们希望将它们都放在基础 class 和 中,而不是 在任何派生的 class 中定义它。唯一的区别是 cm
的调用者 - A
或 B
(或 B1
、B2
中的任何一个,每个继承自 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 问题不同,因为我不想重写 class 方法,而是将其实现完全移至基础 class。
对于 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'
要理解这一点,只要记住 class B 继承了 class A 的 方法 。所以当 __init__()
被调用时B的实例化,它在class B的上下文中被调用,self
指的是
这样看:你的问题本质上是 "How do I get the class of an instance?"。该问题的答案是使用 type
函数:
ClassOfWhateverIsInstantiated = type(self)
但你甚至不需要这样做,因为class方法可以直接通过实例调用:
def __init__(self):
self.attr = self.cm() # just use `self`
这是可行的,因为 class 方法会自动为您查找实例的 class。来自 the docs:
[A classmethod] can be called either on the class (such as C.f()
) or on an instance
(such as C().f()
). The instance is ignored except for its class.
让B
继承自A
。假设 B
的某些行为依赖于 class 属性 cls_x
并且我们希望在构造 B
对象期间设置这种依赖性。由于这不是一个简单的操作,我们希望将其包装在构造函数将调用的 class 方法中。示例:
class B(A):
cls_x = 'B'
@classmethod
def cm(cls):
return cls.cls_x
def __init__(self):
self.attr = B.cm()
问题:cm
和 __init__
将始终做相同的事情,并且它们的行为必须在每个派生的 class 中保持相同。因此,我们希望将它们都放在基础 class 和 中,而不是 在任何派生的 class 中定义它。唯一的区别是 cm
的调用者 - A
或 B
(或 B1
、B2
中的任何一个,每个继承自 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 问题不同,因为我不想重写 class 方法,而是将其实现完全移至基础 class。
对于 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'
要理解这一点,只要记住 class B 继承了 class A 的 方法 。所以当 __init__()
被调用时B的实例化,它在class B的上下文中被调用,self
指的是
这样看:你的问题本质上是 "How do I get the class of an instance?"。该问题的答案是使用 type
函数:
ClassOfWhateverIsInstantiated = type(self)
但你甚至不需要这样做,因为class方法可以直接通过实例调用:
def __init__(self):
self.attr = self.cm() # just use `self`
这是可行的,因为 class 方法会自动为您查找实例的 class。来自 the docs:
[A classmethod] can be called either on the class (such as
C.f()
) or on an instance (such asC().f()
). The instance is ignored except for its class.