在多重继承中,“super”如何与类的“__mro__”属性交互?

2023-12-01

今天,我读到了super 的官方文档.
其中提到多重继承将由__mro__一个类的属性。
所以我做了一些实验,但结果令我惊讶。

# CODE PART
class GrandFather(object):
    def p(self):
        print "I'm old."

class Father(GrandFather):
    def p(self):
        print "I'm male."

class Mother(object):
    def p(self):
        print "I'm female."

class Son(Father, Mother):
    def p(self):
        print "busy, busy, crwaling. "


 # EXPERIMENT PART
In [1]: Son.__mro__
Out[1]: (__main__.Son, __main__.Father, __main__.GrandFather, __main__.Mother, object)

In [2]: Father.__mro__
Out[2]: (__main__.Father, __main__.GrandFather, object)

In [3]: Mother.__mro__
Out[3]: (__main__.Mother, object)

In [4]: GrandFather.__mro__
Out[4]: (__main__.GrandFather, object)

In [5]: s = Son()

In [6]: super(Son, s).p()
I'm male.

In [7]: super(Father, s).p()
I'm old.

In [8]: super(Mother, s).p()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-8-ce4d0d6ef62d> in <module>()
----> 1 super(Mother, s).p()

AttributeError: 'super' object has no attribute 'p'

In [9]: super(GrandFather, s).p()
I'm female.

以下是我上面提到的官方文档的一部分,它说:

super(type[, object-or-type])
Return a proxy object that delegates method calls to a parent or sibling class of type.   
This is useful for accessing inherited methods that have been overridden in a class.  
The search order is same as that used by getattr() except that the type itself is skipped.

The __mro__ attribute of the type lists the method resolution search order  
used by both getattr() and super().   
The attribute is dynamic and can change whenever the inheritance hierarchy is updated.

If the second argument is an object, isinstance(obj, type) must be true.

通过结合这篇文档和我的实验结果。最令人困惑的部分是当调用时super(GrandFather, s).p()它称为p() of Mother, but Mother不在GrandFather's __mro__,并且它的顺序非常低Son's __mro__.

稍微思考了一下之后。我得到了一个看似合理的解释,表明官方文档的不完整或缺陷:
也就是说,当使用 withsuper(type, instance), the super函数将从__mro__的属性class来自谁你的instance是构建,但不是__mro__的属性type你传递到super,即使它满足isinstance(instance, type)健康)状况。

那么当你输入时发生了什么super(Class, instance) is:

  1. Python 检查是否isinstance(instance, Class)是真的。
  2. Python 找到__class__的属性instance,
    得到instance.__class__'s __mro__属性。
  3. Python 查找索引Class你传递到super in the __mro__步骤2中的元组。
  4. Python将step3的索引加1,用它来获取对应的类__mro__步骤2的元组,并返回该对应类的超级委托。
  5. 如果步骤4中的索引超过长度__mro__步骤2的最后一堂课的代表__mro__返回step2的,即object class.

我的理解对吗?
如果我错了,正确的机制是什么super相互作用type's __mro__?
如果我是对的,我应该如何提出 python 官方文档修改的问题?
因为我认为有关此项目的当前版本可能会产生误导。


PS:这个测试是由Python 2.7.6 within IPython 3.2.1.


看着那(这__mro__ of Son:

__main__.Son, __main__.Father, __main__.GrandFather, __main__.Mother, object

根据文档:

The __mro__类型的属性列出了方法解析搜索顺序

因此方法将按照中的顺序进行搜索__mro__列表,从左到右。呼叫super(type, instance)会将起始位置更改为指定为第一个参数的类型super() in the __mro__指定为第二个参数的实例的类列表(如果传递给 super 的第二个参数是一个实例):

super(Son, s)将代理到__main__.Father

super(Father, s)将代理到__main__.GrandFather

super(GrandFather, s)将代理到__main__.Mother

super(Mother, s)将代理到object

有趣的是为什么__mro__ of Son就是这样。换句话说,为什么母亲在追寻祖父。这是因为线性化在 python 中的工作方式:

C 的线性化是 C 的总和加上父级线性化和父级列表的合并。

请参阅中的示例文档你提到的,它解释了一个非常相似的案例。

所以最终的结果实际上是正确的:super(GrandFather, s).p()应该I'm female.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在多重继承中,“super”如何与类的“__mro__”属性交互? 的相关文章

  • Python 切片对象和 __getitem__

    python 中是否有内部的东西来处理传递给的参数 getitem 不同 并自动转换start stop step构造成切片 这是我的意思的演示 class ExampleClass object def getitem self args
  • 如何使用 Python 3 绕过 HTTP Error 403: Forbidden with urllib.request

    您好 不是每次都这样 但有时在尝试访问 LSE 代码时 我会收到每一个烦人的 HTTP 错误 403 禁止消息 任何人都知道我如何仅使用标准 python 模块来克服这个问题 遗憾的是没有漂亮的汤 import urllib request
  • 从文本文件中删除特定字符

    我对 Python 和编码都很陌生 我当时正在做一个小项目 但遇到了一个问题 44 1 6 23 2 7 49 2 3 53 2 1 68 1 6 71 2 7 我只需要从每行中删除第三个和第六个字符 或者更具体地说 从整个文件中删除 字符
  • 反编译Python 3.9.2的PYC文件[重复]

    这个问题在这里已经有答案了 目前 我有一个 3 9 2 版本的 python 的 PYC 文件 P S 这适用于所有 3 9 及更高版本 我正在尝试反编译 PYC 文件 但它显示错误 因为 uncompyle6 或者更确切地说 新版本 de
  • Mypy 无法从文字列表推断项目的类型

    我有一个变量x和一个文字列表 例如 0 1 2 我想转换x这些文字之一 如果x在列表中 我将其退回 否则我返回一个后备值 from typing import Literal Set Foo Literal 0 1 2 foos Set F
  • 如何过滤 Pandas GroupBy 对象并获取 GroupBy 对象?

    当对 Pandas groupby 操作的结果执行过滤时 它返回一个数据帧 但假设我想执行进一步的分组计算 我必须再次调用 groupby 这似乎有点绕 有更惯用的方法吗 EDIT 为了说明我在说什么 我们无耻地从 Pandas 文档中窃取
  • 使用python从gst管道抓取帧到opencv

    我在用着OpenCV http opencv org 和GStreamer0 10 我使用此管道通过自定义套接字通过 UDP 接收 MPEG ts 数据包sockfd由 python 提供并显示它xvimagesink 而且效果很好 以下命
  • AttributeError:“模块”对象没有属性[重复]

    这个问题在这里已经有答案了 我有两个 python 模块 a py import b def hello print hello print a py print hello print b hi b py import a def hi
  • Paste.httpserver 并通过 HTTP/1.1 Keep-alive 减慢速度;使用 httperf 和 ab 进行测试

    我有一个基于paste httpserver 的Web 服务器作为HTTP 和WSGI 之间的适配器 当我使用 httperf 进行性能测量时 如果每次使用 num conn 启动一个新请求 我每秒可以执行超过 1 000 个请求 如果我使
  • 两个不同长度的数据帧的列之间的余弦相似度?

    我在 df1 中有文本列 在 df2 中有文本列 df2 的长度将与 df1 的长度不同 我想计算 df1 text 中每个条目与 df2 text 中每个条目的余弦相似度 并为每场比赛给出分数 输入样本 df1 mahesh suresh
  • 查找 Pandas DF 行中的最短日期并创建新列

    我有一个包含多个日期的表 有些日期将为 NaN 我需要找到最旧的日期 所以一行可能有 DATE MODIFIED WITHDRAWN DATE SOLD DATE STATUS DATE 等 因此 对于每一行 一个或多个字段中都会有一个日期
  • 给定一个排序数组,就地删除重复项,使每个元素仅出现一次并返回新长度

    完整的问题 我开始在线学习 python 但对这个标记为简单的问题有疑问 给定一个排序数组 就地删除重复项 使得每个 元素只出现一次并返回新的长度 不分配 另一个数组的额外空间 您必须通过修改输入来完成此操作 数组就地 具有 O 1 额外内
  • 在骨架图像中查找线 OpenCV python

    我有以下图片 我想找到一些线来进行一些计算 平均长度等 我尝试使用HoughLinesP 但它找不到线 我能怎么做 这是我的代码 sk skeleton mask rows cols sk shape imgOut np zeros row
  • minizinc python 安装

    我通过 anaconda 提示符在 python 上安装了 minizinc 就像其他软件包一样 pip install minizinc 该软件包表示已成功安装 我可以导入该模块 但是 我正在遵循基本示例https minizinc py
  • 带 Flask 的 RPI dht22:无法将第 4 行设置为输入 - 等待 PulseIn 消息超时

    我正在尝试制作一个 Raspberry Pi 3 REST API 使用 DHT22 提供温度和湿度 整个代码 from flask import Flask jsonify request from sds011 import SDS01
  • 如何获取pandas中groupby对象中的组数?

    我想知道有多少个独特的组需要执行计算 给定一个名为 groupby 的对象dfgroup 我们如何找到组的数量 简单 快速 Pandaic ngroups 较新版本的 groupby API pandas gt 0 23 提供了此 未记录的
  • IndexError - 具有匀称形状的笛卡尔 PolygonPatch

    我曾经使用 shapely 制作一个圆圈并将其绘制在之前填充的图上 这曾经工作得很好 最近 我收到索引错误 我将代码分解为最简单的操作 但它甚至无法执行最简单的循环 import descartes import shapely geome
  • 如何(安全)将 Python 对象发送到我的 Flask API?

    我目前正在尝试构建一个 Flask Web API 它能够在 POST 请求中接收 python 对象 我使用 Python 3 7 1 创建请求 使用 Python 2 7 运行 API 该 API 设置为在我的本地计算机上运行 我试图发
  • 定义在文本小部件中双击时选择哪些字符

    在 Windows 上 双击文本小部件中的单词也将选择连接的标点符号 有什么方法可以定义您想要选择的角色吗 tcl wordchars该变量的值是一个正则表达式 可以设置它来控制什么被视为 单词 字符 例如 通过双击 Tk 中的文本来选择单
  • 无法安装最新版本的 Numpy (1.22.3)

    我正在尝试安装最新版本的 numpy 即 1 22 3 但看起来 pip 无法找到最后一个版本 我知道我可以从源代码本地安装它 但我想了解为什么我无法使用 pip 安装它 PS 我有最新版本的pip 22 0 4 ERROR Could n

随机推荐

  • 返回函数 c 中的结构

    我正在尝试返回一个struct来自一个函数 看起来是这样的 struct read struct returnera returnDuo struct vara varuArray char varunr LISTNUMBER varuna
  • 在本地开发时在 Cloud Run 中模拟事件驱动设计?

    我正在开发一个在 Google Cloud Run 完全托管 上 运行的微服务架构应用程序 我想将事件通信添加到我的服务中 据我所知 唯一的选择是使用 Eventarc 我很好奇在本地开发时重现事件驱动设计的最佳方法是什么 以及如何使部署尽
  • 如何在 Scala Spark 中从 Excel(xls、xlsx)文件构造 Dataframe?

    我有一个大Excel xlsx and xls 包含多个工作表的文件 我需要将其转换为RDD or Dataframe以便它可以连接到其他dataframe之后 我正在考虑使用阿帕奇兴趣点并将其另存为CSV然后阅读csv in datafr
  • 如何在没有注解的情况下使用Spring Data JDBC?

    我正在开发一个新项目 使用干净架构等概念 保护我的模型和业务规则免受外部依赖项和框架的影响 另外 我不喜欢使用传统的 ORM 库 如 JPA Hibernate 而是选择使用纯 jdbc 通过 spring jdbctemplate 一切进
  • 如何按添加顺序绘制 X、Y 坐标?

    我想按照我输入的顺序连接 X 和 Y 坐标以形成一个圆 我找到了一个用Java绘制X Y坐标的程序 然后我添加了圆的数据 但程序连接了最近的 X Y 坐标 而不是排序 X Y public Graph final String title
  • SQLAlchemy ORM 无法使用复合外键

    我正在尝试使用几个相关模型构建一个示例 如下所示 我们有一个模型 B 与模型 C 具有 1 n 关系 那么我们就有一个模型 A 与 B 之间存在 n 1 关系 与 C 之间存在 n 1 关系 C 有 2 列主键 我尝试了这段代码 class
  • 按键在 Mozilla Firefox 中不起作用

    我有一项任务限制文本框的字母值 只能使用浮点值 小数点后我们必须写出两位数 我这样做了 但它在 Mozilla Firefox 中不起作用 我怎么解决这个问题 我的脚本是 function name bind paste function
  • 如何使用正则表达式提取大括号中的单词?

    我想提取全部words用花括号括起来 所以我有这样的表达式 foo bar moo mar 要匹配的字符串可能有任意数量的这些单词 但我开始认为我正在以错误的方式处理这个问题 我的尝试 我尝试将大括号中的单词提取到组中 以便我可以使用每个匹
  • Cocoa:隐藏其他应用程序和自身

    我需要一种方法让应用程序与所有其他应用程序一起隐藏自身 我目前隐藏了其他应用程序 但我的应用程序保持打开状态 我通过单击按钮并将其拖动到实用程序中的 应用程序 区域来完成此操作 然后我选择 隐藏其他应用程序 好的 所以 如果你只是想show
  • 在 React 和 Next.js 构造函数中,我收到“引用错误:本地存储未定义”

    我在 React 中创建了一个系统 jsonwebtoken 并使用 Next js 在浏览器中运行代码时发现一个问题 那就是 本地存储未定义 我该如何修复它 这是我在文件中的代码AuthStudentContext js import R
  • 如何翻译/移动 numpy 数组?

    我不确定要搜索什么关键字 因此如果已被询问 请链接响应并关闭此线程 我试图按固定方向移动 numpy 数组的非零条目 例如 假设我有一个二维数组 0 1 2 0 0 3 0 0 0 0 0 0 0 0 0 0 将其移位 1 1 将产生以下数
  • 海龟图形在自身上绘制

    这应该是一个非常简单的问题 然而 事实证明这对我来说很难 我对海龟图形相当陌生 因此 我正在尝试完成简单的绘图 我的乌龟会画一行 拿起笔 向上移动一个像素 放下笔 然后继续绘画 到目前为止 这是我的代码 for y in range hei
  • 如何从 spring mvc multipartfile 进入 zipinputstream

    我有一个 Spring MVC 控制器 它接受 MultipartFile 它将是一个 zip 文件 问题是我似乎无法从那里转到 ZipInputStream 或 ZipFile 以便我可以浏览条目 它要么提前关闭流 生成一个空文件 要么像
  • 如何在从服务器获取数据的动态表的每一行中添加下拉列表?

    我想添加静态下拉列表到从服务器获取数据的动态表的每一行 我将如何做到这一点 我想做同样的像这样 请检查下拉列表类型 但它也会从服务器获取数据 并且每一行列都会有下拉列表 以下是更新和工作代码 感谢 angu 下拉列表的结构
  • C++中的输出流什么时候必须刷新?

    我明白cout lt lt n 优先于cout lt lt endl but cout lt lt n 不刷新输出流 何时应该刷新输出流以及何时出现问题 究竟什么是潮红 刷新强制输出流写入任何缓冲的字符 读取流式输入 输出 这取决于您的应用
  • 如何解决带有日期值的 h:inputText 中的“‘null Converter’的转换错误设置值‘2013-10-26’”?

    当我按下插入按钮时 标题上显示错误 空转换器 的转换错误设置值 2013 10 26
  • 为什么我不能先定义 main(),然后再定义它调用的函数?

    如果我将 main 放在源文件的顶部并调用一些自定义函数 它会告诉我找不到这些函数 但如果我将 main 放在源文件的底部 它将起作用 为什么 是不是因为编译器从上到下解析程序并在main的定义处中断 和main没有关系 C 编译器从上到下
  • OpenTK 矩阵变换

    这是顶点着色器 uniform mat4 projection uniform mat4 view uniform mat4 model void main void gl Position projection view model gl
  • else, elif, if Python中的问题

    instrument raw input Which kind of tab would you like to view Enter Guitar or Bass for a random tab print if instrument
  • 在多重继承中,“super”如何与类的“__mro__”属性交互?

    今天 我读到了super 的官方文档 其中提到多重继承将由 mro 一个类的属性 所以我做了一些实验 但结果令我惊讶 CODE PART class GrandFather object def p self print I m old c