首页 新闻 会员 周边 捐助

super()作用?

0
[已解决问题] 解决于 2025-08-25 11:23

help on class super in module builtins:在内置模块 builtins 里,关于 class super 的帮助信息”

_java_python的主页 _java_python | 小虾三级 | 园豆:984
提问于:2025-08-25 11:19
< >
分享
最佳答案
0
class super(object)
   super()->same as super(__class__,<first argument>)
   super(type) -> unbound super object
   super(type,obj) -> bound super object: requires isinstance(obj,type)
   super(type,type2) -> bound super object;requires issubclass(type2,type)
Typical use to call a cooperative superclass method:

type 指的是 子类本身(即当前类)。
super(type, obj)
type 写当前子类的名字,obj 写子类实例。
例:super(Child, self) 表示“从 Child 的父类开始找方法,并把 self 绑定进去”。
super(type, type2)
type 仍是子类,type2 通常也是同一个子类(或更子类)。
super(type) 返回的是一个 未绑定(unbound) 的 super 对象,
它没有绑定任何实例,因此不能直接调用实例方法(实例方法第一个参数必须是 self)

第一个参数 type:“从谁开始往上找父类”(通常写当前子类)。
第二个参数 obj:“把谁当作 self/cls 传进去”,必须是 type 的实例或子类(实例或类对象皆可)。

uper(Child) 返回的是 未绑定 的 super 对象,它 没有绑定任何实例或类,因此:
如果你调用的是 实例方法(需要 self),就会缺少第一个参数,触发 TypeError。
只有 类方法 / 静态方法 才能用未绑定 super,但也必须显式传入类对象。

# 实例方法:必须绑定实例
super(Child, instance).method()

# 类方法:可以绑定类
super(Child, Child).classmethod()

super() 是一个函数,调用后返回一个用于访问父类方法的代理对象。

• 它的核心价值在于动态遵循继承链,避免硬编码父类名,使代码在继承结构变化时更灵活。

• 实际开发中,super().方法() 是最常用的写法,隐含了当前类和实例的上下文。

_java_python | 小虾三级 |园豆:984 | 2025-08-25 11:20
super() 的完整签名其实长这样:
super([cls[, instance]]) -> 代理对象     [] 是BNF/语法手册里的“可选”记号
  • 如果两个参数都省略(也就是日常写的 super()), Python 会在编译阶段自动把当前类名和第一个入参 self 填进去,
    效果等价于:
super(__class__, self) # 在实例方法里
这两个东西就是:
  1. __class__
    编译器在当前函数体内偷偷插入的一个闭包变量,指向正在定义的这个类对象本身。
    所以写 super() 时你不必硬编码类名,改名/重构都不会崩。
  2. <first argument>
    实例方法里的第一个参数,通常是 self
    它必须是一个实例,而且它的 __class__ 要在 cls 的继承链里,否则 super 无法确定方法解析顺序(MRO)。
一句话:
super() 就是语法糖,帮你把“当前类”和“当前实例”自动塞进 super(__class__, self),省得你手写类名、不怕以后改继承层次。
class A: pass
class B(A): pass

b = B()
继承链(MRO)就是 B → A → object。
现在你可以写:
super(B, b)   # OK,b 的 __class__ 就是 B
super(A, b)   # 同样 OK,b 的 __class__  B 是 A 的子类,A 在 b 的 MRO 里
但如果你写:
class C: pass          # 与 A、B 无关的独立类
c = C()
super(A, c)            # TypeError: super(cls, obj): obj 必须是 cls 的实例或子类的实例

  Animal
          ↑
        Mammal
          ↑
        Dog

如果 cls = Animal
那么 obj 可以是 Animal、Mammal、Dog 的实例——它们都在 Animal 的继承链下面。
如果 cls = Mammal
obj 可以是 Mammal 或 Dog 的实例,不能是 Animal 的实例,因为 Animal 在 Mammal 上面,不是“子类”。

class Animal: pass
class Mammal(Animal): pass
class Dog(Mammal): pass

dog = Dog()

super(Animal, dog)   # OK,Dog 是 Animal 的子类
super(Mammal, dog)   # OK,Dog 是 Mammal 的子类
super(Dog, dog)      # OK,自己
super(object, dog)   # OK,最终基类

super(Dog, Animal())   # TypeError

一句话:“cls 必须是 obj 的祖先类” —— 也就是 obj 的类要在 cls 的继承链下方(或重合

 super(cls, 任意子类对象) 完全合法,只要那个对象的类确实继承自 cls,第二个参数不必是 self

 
class Animal:
    def speak(self):
        print("Animal")

class Dog(Animal):
    def speak(self):
        print("Dog")

class Husky(Dog):
    def speak(self):
        print("Husky")

# ---- 在 Animal 里手动指定子类对象 ----
class Logger:
    def log(self, any_obj):          # 任何子类对象都行
        print("Logger")
        super(Animal, any_obj).speak()   # 不用 self,用传进来的子类对象

logger = Logger()
dog  = Dog()
husky = Husky()

logger.log(dog)     # 输出 Logger -> Dog
logger.log(husky)   # 输出 Logger -> Husky

 

 print(dir(__builtins__))可以看到所有内置函数

python中,super是一个特殊函数,帮助python把父类和子类关联起来的,专门在子类里用;

 

  • 最常见的用途:在子类重写的方法里先调用 super().原方法(),从而把父类的逻辑拿过来继续用,实现真正的“扩展”而不是“覆盖掉”。
_java_python | 园豆:984 (小虾三级) | 2025-09-07 14:57
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册