Python中super(type, obj) 和 super(type, type)的区别在哪?
class Person:
def __init__(self, name):
self.name = name
# Getter function
@property
def name(self):
return self._name
# Setter function
@name.setter
def name(self, value):
if not isinstance(value, str):
raise TypeError('Expected a string')
self._name = value
# Deleter function
@name.deleter
def name(self):
raise AttributeError("Can't delete attribute")
class SubPerson(Person):
@property
def name(self):
print(‘Getting name’)
return super().name
@name.setter
def name(self, value):
print(‘Setting name to’, value)
super(SubPerson, SubPerson).name.set(self, value)
@name.deleter
def name(self):
print(‘Deleting name’)
super(SubPerson, SubPerson).name.delete(self)
s = SubPerson(‘Guido’)
print(s.name)
当我将 super(SubPerson, SubPerson).name.__set__(self, value) 变成
super(SubPerson, self).name.__set__(self, value), 报了这样的错误
AttributeError: 'SubPerson' object has no attribute '_name'
为什么?
Python中super(type, obj) 和 super(type, type)的区别在哪?
super(type, obj) 和 super(type, type) 的核心区别在于第二个参数 obj 或 type 决定了返回的 super 对象绑定到哪个实例(或类),这直接影响了后续方法解析顺序(MRO)的查找起点。
1. super(type, obj)
- 作用:返回一个绑定到实例
obj的super对象。 - 要求:
obj必须是type的实例(或子类实例)。 - 行为:调用方法时,会从
type在 MRO 中的下一个类开始查找,并将obj作为self自动传入。 - 典型用途:在实例方法中调用父类方法,例如
super(CurrentClass, self).some_method()。
2. super(type, type)
- 作用:返回一个绑定到类
type的super对象。 - 要求:第二个
type必须是第一个type的子类(或它本身)。 - 行为:调用方法时,会从
type在 MRO 中的下一个类开始查找,但期望方法是@classmethod装饰的类方法,因为调用时会自动将第二个type作为cls传入。 - 典型用途:在类方法中调用父类的类方法,例如
super(CurrentClass, cls).some_classmethod()。
代码示例对比:
class A:
def method(self):
return "A.method"
@classmethod
def class_method(cls):
return "A.class_method"
class B(A):
def method(self):
# 绑定到实例 self,查找 A.method
return super(B, self).method() + " -> B.method"
@classmethod
def class_method(cls):
# 绑定到类 cls,查找 A.class_method
return super(B, cls).class_method() + " -> B.class_method"
b = B()
print(b.method()) # 输出: A.method -> B.method
print(B.class_method()) # 输出: A.class_method -> B.class_method
关键点总结:
super(type, obj)用于实例方法,自动绑定实例obj作为self。super(type, type)用于类方法,自动绑定类type作为cls。- 在 Python 3 中,你可以简写为
super()(在实例方法中)和super()(在类方法中),编译器会自动填充正确的参数。
一句话建议: 根据你是在实例方法还是类方法中调用,来正确选择 super 的绑定对象。
标准里面没有 super(SubPerson, SubPerson) 这种写法吧……即使你手头的 CPython 能工作,也不代表未来的 CPython,或者别的 Python 比如 IronPython 和 PyPy 能工作。建议规避掉这种写法。
我已经知道问题所在,结贴了:)

