Asa*_*svi 8 python inheritance python-3.x
从Python3的文档super()"返回一个代理对象,它将方法调用委托给父类或兄弟类的类型." 那是什么意思?
假设我有以下代码:
class SuperClass():
def __init__(self):
print("__init__ from SuperClass.")
print("self object id from SuperClass: " + str(id(self)))
class SubClass(SuperClass):
def __init__(self):
print("__init__ from SubClass.")
print("self object id from SubClass: " + str(id(self)))
super().__init__()
sc = SubClass()
Run Code Online (Sandbox Code Playgroud)
我得到的输出是:
__init__ from SubClass. self object id from SubClass: 140690611849200 __init__ from SuperClass. self object id from SuperClass: 140690611849200
这意味着,在该线super().__init__(),super()正在返回其然后隐式地传递到父类的当前对象__init__()的方法.这是准确的还是我错过了什么?
简单来说,我想了解以下内容:
什么时候super().__init__()跑,
__init__()怎么样?我们正在调用它,super()所以无论返回什么,都应该__init__()从我对Python的理解到目前为止传递给方法.self进入super().__init__()?返回一个代理对象,该方法将方法调用委托给父类或兄弟类的类型.
这proxy是一个充当父类的方法调用部分的对象.这不是班级本身; 相反,它只是足够的信息,因此您可以使用它来调用父类方法.
如果您打电话__init__(),您将获得自己的本地子类__init__功能.当您调用时super(),您将获得该代理对象,该对象将重定向到父类方法.因此,当您调用时super().__init__(),该代理会将调用重定向到父类__init__方法.
同样,如果您要调用super().foo,您将从foo父类中获取该方法 - 再次由该代理重新路由.
你明白了吗?
对OP评论的回应
但这必须意味着在运行super()时将此代理对象传递给 init().init()对不对?
错误.代理对象就像包名,例如调用math.sqrt().你没有将数学传递给sqrt,你用它来表示你正在使用哪个sqrt.如果你想将代理传递给init,那么调用将是init(super()).当然,这种呼吁在语义上是荒谬的.
当我们必须实际传入self时,我的例子中是sc对象.
不,你没有进来sc; 那就是结果对象创建呼叫(内部方法__new__),其中包括的调用init.因为__init__,该self对象是Python运行时系统为您创建的新项目.对于大多数类方法,第一个参数(在其他语言中称为self约定this)是调用该方法的对象.
这意味着,在该线
super().__init__(),super()正在返回其然后隐式地传递到父类的当前对象__init__()的方法。这是准确的还是我在这里遗漏了什么?
>>> help(super)
super() -> same as super(__class__, <first argument>)
Run Code Online (Sandbox Code Playgroud)
super call 返回一个代理/包装器对象,它记住:
实例调用 super()
调用对象的类
调用的类 super()
这是完美的声音。super始终获取具有您要查找的属性的层次结构中的下一个类(实际上是 MRO)的属性。所以它不是返回当前对象,而是更准确地说,它返回一个对象,它记住足够的信息来搜索类层次结构中更高的属性。
- 究竟传递给什么
__init__()以及如何传递?我们正在调用它,super()所以无论返回什么,都应该根据__init__()我目前对 Python 的理解传递给方法。
你几乎是对的。但super喜欢捉弄我们。super类定义__getattribute__,该方法负责属性搜索。当您执行以下操作时:super().y(),super.__getattribute__被称为搜索y。一旦它找到y它传递的是真实调用实例super调用y。另外,superhas__get__方法,使它成为一个描述符,这里我将省略描述符的详细信息,请参阅文档以了解更多信息。这也回答了您的第二个问题,即为什么self没有明确通过。
*注意:super有点不同,依赖于一些魔法。几乎所有其他类的行为都是相同的。那是:
a = A() # A is a class
a.y() # same as A.y(a), self is a
Run Code Online (Sandbox Code Playgroud)
但super不同的是:
class A:
def y(self):
return self
class B(A):
def y(self)
return super().y() # equivalent to: A.y(self)
b = B()
b.y() is b # True: returns b not super(), self is b not super()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2651 次 |
| 最近记录: |