为什么 python 不利用 __iadd__ 来求和和链式运算符?

2024-01-26

我刚刚进行了一个有趣的测试:

~$ python3 # I also conducted this on python 2.7.6, with the same result
Python 3.4.0 (default, Apr 11 2014, 13:05:11) 
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> class Foo(object):
...     def __add__(self, other):
...         global add_calls
...         add_calls += 1
...         return Foo()
...     def __iadd__(self, other):
...         return self
...
>>> add_calls = 0
>>> a = list(map(lambda x:Foo(), range(6)))
>>> a[0] + a[1] + a[2]
<__main__.Foo object at 0x7fb588e6c400>
>>> add_calls
2
>>> add_calls = 0
>>> sum(a, Foo())
<__main__.Foo object at 0x7fb588e6c4a8>
>>> add_calls
6

显然,__iadd__方法比以下方法更有效__add__方法,不需要分配新类。如果我添加的对象足够复杂,这将创建不必要的新对象,可能会在我的代码中造成巨大的瓶颈。

我希望,在一个a[0] + a[1] + a[2],第一个操作将调用__add__,第二个操作将调用__iadd__在新创建的对象上。

为什么python不优化这个呢?


The __add__方法可以自由返回不同类型的对象,而__iadd__如果使用就地语义,应该返回self。他们不需要在这里返回相同类型的对象,所以sum()不应依赖于特殊语义__iadd__.

您可以使用functools.reduce()功能 https://docs.python.org/3/library/functools.html#functools.reduce自己实现您想要的功能:

from functools import reduce

sum_with_inplace_semantics = reduce(Foo.__iadd__, a, Foo())

Demo:

>>> from functools import reduce
>>> class Foo(object):
...     def __add__(self, other):
...         global add_calls
...         add_calls += 1
...         return Foo()
...     def __iadd__(self, other):
...         global iadd_calls
...         iadd_calls += 1
...         return self
... 
>>> a = [Foo() for _ in range(6)]
>>> result = Foo()
>>> add_calls = iadd_calls = 0
>>> reduce(Foo.__iadd__, a, result) is result
True
>>> add_calls, iadd_calls
(0, 6)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 python 不利用 __iadd__ 来求和和链式运算符? 的相关文章

随机推荐

  • cassandra CQL 中的内连接

    如何在 cassandra 中编写子查询 嵌套查询 CQL 中是否提供了此功能 我尝试过的例子 cqlsh testdb gt select itemname from item where itemid select itemid fro
  • Docker compose找不到本地包

    因此 我在 GOlang 中创建了 REST api 和一个 grpc 服务 现在我想在 docker compose 中组合它 我的 docker compose 看起来像这样 version 3 services db image po
  • 在同一台计算机上运行 Internet Explorer 6、Internet Explorer 7 和 Internet Explorer 8

    和其他人一样 我需要在 Internet Explorer 6 和 Internet Explorer 7 上测试我的代码 现在 Internet Explorer 8 为开发人员提供了一些很棒的工具 我想使用它们 我还想开始使用 Inte
  • 在bat文件中查询npm错误状态

    我们目前正在将 UI 项目 总共 3 个 的构建转移到 Grunt 为了简化转换 我想提供一个可以运行的bat文件npm install对于每个项目 但是我想知道发出此命令时是否出现问题 我所追求的只是糖衣 我知道 npm 会回显错误 但我
  • psql: FATAL: 用户 PAM 身份验证失败

    PostgreSQL 9 2 4 我无法再使用过去工作过的用户登录 我假设配置有问题 因此 为了进行测试 我创建了一个测试用户角色 testing 其选项与相关角色相同 作为仍然可以登录的 postgres 用户 CREATE ROLE t
  • 如何在Python 2.7中实现带超时的锁

    有没有一种方法可以在Python中实现多线程锁acquire方法可以有任意超时吗 到目前为止我发现的唯一可行的解 决方案使用轮询 这 我觉得不优雅而且效率低下 不保留锁的有界等待 进度保证作为临界区问题的解决方案 有没有更好的方法来实现这个
  • IList 到 IQueryable

    我有一个列表 我想将其包装到 IQueryable 中 这可能吗 List
  • 使用 C# 进行 AES 加密 使用 crypto-js 进行解密

    我正在尝试使用 C 加密字符串并使用 Angular crypto js 库解密它 但它给了我不同的输出 我尝试了不同的 c aes 加密实现 但 crypto js 库无法解密 c 中的加密数据 感谢您的任何帮助 这是我的代码 程序 cs
  • 覆盖 DICOM 中的像素数据时应替换哪些 DICOM UID?

    我正在尝试从现有文件创建一个新的 DICOM 文件 实例 并在其中更改像素数据 我知道在替换像素数据时需要更改一些 UID 目前我正在生成SOPInstanceUID MediaStorageSOPInstanceUID and Refer
  • 将 HTML 字符串附加到 DOM

    如何附加 HTML 字符串 例如 var str p Just some span text span here p to the div 与身份证test Btw div innerHTML str 是不能接受的 Use insertAd
  • 如何将 Swagger 无配置设置与 Jersey 2 集成

    我正在尝试使用 Tomcat 8 5 上托管的 Jersey 2 项目进行准系统 Swagger 设置 我首先使用 Jersey 入门指南中的以下代码片段生成了 Jersey 项目 https jersey github io docume
  • Ajax请求问题:错误80020101

    我有一个返回 jsp 页面的请求 但事实是 jsp 中包含 jsp include 它调用其中的另一个 jsp 文件 并且 ie 给出错误 80020101 有任何想法吗 Thanks 如果您从 jQuery 进行 AJAX 调用并且在数组
  • Laravel 的多重身份验证

    我想将中间件身份验证分为两个角色 第一个角色用于管理员 第二个角色用于用户 但有些路线供所有用户和管理员使用 而少数路线仅供管理员使用 我如何与路线分开 Auth routes Route group middleware gt auth
  • 在 Oracle SQL 中计算 2 个日期/时间之间的差异

    我有一个表如下 Filename varchar Creation Date Date format dd mm yyyy hh24 mi ss Oldest cdr date Date format dd mm yyyy hh24 mi
  • 如何让 Spring-Data-MongoDB 来验证我的对象?

    我有一个非常简单的 Spring Boot 应用程序 它使用 Spring Data Mongodb 我想要做的就是设置一个 JSR 303 验证规则 规定我要保存的对象必须有用户名 我读到 JSR 303 已添加到 spring data
  • 使用 LayoutInflator 的 inflate 方法时的不同结果

    我想知道如何LayoutParams将致力于LayoutInflator 两者之间有什么区别 LinearLayout childLayout LinearLayout inflater inflate R layout childitem
  • Azure应用服务:无法保存应用程序设置

    我可以设置应用程序设置和连接字符串 但无法保存它们 尽管我进行了更改 该按钮仍然处于禁用状态 我有 3 个应用程序 只关注其中一个 我是订阅的管理员 有什么想法吗 要克服这个 Azure Portal 问题 您可以使用 powerShell
  • 使用 XmlHttpRequest 时是否有任何方法可以抑制浏览器在 401 响应上的登录提示

    我正在使用 jQuert ajax 函数来调用页面方法 该网站正在使用 FormsAuthentication 因此 当身份验证票证过期时 对页面方法的调用显然会导致重定向到登录页面 现在 编写 System Web Handlers Sc
  • Service Fabric 容器项目可以从 Docker Hub 中提取吗?

    我在 Visual Studio 中创建了一个新的 Service Fabric 容器项目 并尝试通过发布到本地集群来测试该项目 我创建了一个 Windows 容器映像 并在 Docker 中本地运行 我将镜像推送到 Docker Hub
  • 为什么 python 不利用 __iadd__ 来求和和链式运算符?

    我刚刚进行了一个有趣的测试 python3 I also conducted this on python 2 7 6 with the same result Python 3 4 0 default Apr 11 2014 13 05