- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
python的documentation on the methods related to the in-place operators类似于+=
和*=
(或者,正如它所说的,增加的算术赋值)有以下说法:
这些方法应该尝试就地执行操作(修改self)并返回结果(可能是self,但不一定是self)。如果未定义特定的方法,则增强的赋值将返回到普通方法。
我有两个密切相关的问题:
如果文档指定,如果实现了这些方法,那么它们应该只在适当的地方进行工作,那么为什么需要从这些方法返回任何东西呢?为什么在实现了__iadd__
的情况下,增广的赋值操作符不简单地执行冗余赋值?
在什么情况下,从增广的赋值方法返回self
之外的内容是有意义的?
一些实验表明,python的不可变类型不实现__iadd__
(与引用的文档一致):
>>> x = 5
>>> x.__iadd__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute '__iadd__'
__iadd__
方法是就地操作并返回
self
:
>>> list1 = []
>>> list2 = list1
>>> list1 += [1,2,3]
>>> list1 is list2
True
self
返回
__iadd__
之外的内容的功能是什么。在任何情况下都这样做似乎是错误的。
最佳答案
如果文档指定,如果实现了这些方法,那么它们应该只在适当的地方进行工作,那么为什么需要从这些方法返回任何东西呢?为什么在实现了__iadd__
的情况下,增广的赋值操作符不简单地执行冗余赋值?
一个原因是强迫它们成为语句而不是表达式。
一个更大的原因是任务并不总是多余的。在左侧只是一个变量的情况下,当然,在改变对象之后,通常不需要将该对象重新绑定到它已经绑定到的名称。
但是,如果左手边是一个更复杂的任务目标,那该怎么办呢?记住you can assign—and augmented-assign—to subscriptions, slicings, and attribute references,如a[1] += 2
或a.b -= 2
。在这种情况下,您实际上是在对象上调用__setitem__
或__setattr__
,而不仅仅是绑定一个变量。
另外,值得注意的是,“冗余分配”并不是一个昂贵的操作。这不是C++,任何赋值都可以在值上调用自定义赋值操作符。(最后可能会在值是元素、子片或属性的对象上调用自定义setter运算符,这可能很昂贵……但在这种情况下,它不是多余的,如上所述。)
最后一个原因直接关系到第二个问题:你几乎总是想从self
返回__ispam__
,但几乎总是不总是。如果__iadd__
ever没有返回self
,那么分配显然是必要的。
在什么情况下,从增广的赋值方法返回除self以外的东西是有意义的?
你在这里略读了一个重要的相关内容:
这些方法应尝试就地执行操作(修改自身)
在任何情况下,如果他们不能在适当的位置执行操作,但可以执行其他操作,则可能会合理地返回self
以外的操作。
假设一个对象使用了一个copy-on-write实现,如果它是唯一的副本,那么它会在适当的位置发生变化,但是会生成一个新的副本。不能通过不实现__iadd__
并让+=
返回到__add__
来实现;只能通过实现可能生成并返回副本而不是突变并返回__iadd__
来实现。(出于性能原因,您可能会这样做,但也可以想象,您拥有一个具有两个不同接口的对象;“高级别”接口看起来是不可变的,“写时复制”,“低级别”接口公开实际共享。)
所以,它需要的第一个原因是处理非就地案例。
但还有其他原因吗?当然.
其中一个原因是包装其他语言或库,而这是一个重要的特性。
例如,在目标C中,许多方法返回一个self
通常是但不总是收到方法调用的同一个对象。objc处理类集群之类的事情的方式“并不总是”。在Python中,有更好的方法来做同样的事情(即使在运行时更改类通常也更好),但是在objc中,这是完全正常和惯用的。(它只用于苹果当前框架中的self
方法,但它是标准库的一个约定,由init
添加的mutator方法始终返回NSMutableFoo
,就像在python中mutator方法(如void
始终返回list.sort
)的约定,而不是语言的一部分。)所以,如果你想用python总结objc运行时,您将如何处理它?
您可以在所有内容前面放置一个额外的代理层,这样您的包装器对象就可以更改它包装的对象objc。但这意味着大量复杂的委托代码(特别是如果您想让objc反射通过包装器回到python中工作的话)和内存管理代码,并且性能会受到影响。
相反,您可以只拥有一个通用的瘦包装器。如果返回一个与开始时不同的objc对象,则返回围绕该对象的包装器,而不是围绕您开始时的对象的包装器。琐碎的代码,内存管理是自动的,没有性能成本。只要包装器的用户总是执行None
而不是a += b
操作,他们就不会看到任何差异。
我意识到“在一个不同的Objc框架库中编写一个PyObjc风格的包装,而不是苹果的基础”并不是一个日常的用例,但是你已经知道这是一个你每天都不用的特性,那么你还能期待什么呢?
一个懒惰的网络对象代理可能会做一些类似的事情,从一个很小的名字对象开始,当你第一次尝试对它做一些事情时,把它换成一个完整的代理对象。你可能会想到其他这样的例子。你可能永远也不会写它们……但是如果你不得不写,你可以。
关于python - 为什么从`__iadd__`返回除“self”之外的任何东西?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20849870/
我正在努力解决一个问题 Rahul 正在玩一个非常有趣的游戏。他有 N 个圆盘(每个圆盘的半径相等)。每个磁盘都有一个不同的数字,从 1 到 N 与之相关联。磁盘一个接一个地放在一堆中。 Rahul
我正在尝试使用此代码发出请求: public JsonObject account() throws BinanceApiException { return (new Request
我使用的是 Mac OS 和 emacs -nw (终端模式)。 我不知道如何在 emacs 之外粘贴东西(已由 M-w 在 emacs -nw 中实现)。 我知道emacs -ns可以做到。 搜索互
我试图让导航栏菜单出现在“标题容器”菜单中,但由于某种原因,导航栏链接流到外面(在修改浏览器窗口之前)。我不明白为什么,但我怀疑它与这一行有关: div class="collapse navbar-
我们的项目是在 WAS 6.1/hibernate/struts 上使用 RAD 7.0 开发的中型 Web 应用程序,该应用程序已投入生产。目前我们在属性文件中硬编码了生产系统的 IP 地址,在 h
我的要求是在传单中创建 N 类型的标记。该列表很大,无法容纳在 map 区域中。 我想要类似的东西: http://blog.georepublic.info/2012/leaflet-example
如 docs 中所述,基于 spring-boot 的 Web 服务正在使用 Sentry .它工作正常,但不应将某些异常发送到 Sentry ,例如为了在某些请求上返回 HTTP 状态 410
我已经阅读了 Apple Core Animation 文档。它说核心动画没有提供在窗口中实际显示图层的方法,它们必须由 View 托管。当与 View 配对时, View 必须为底层图层提供事件处理
我试图在滚动时检查元素是否在我的视口(viewport)内。如果它在我的视口(viewport)之外,我会添加一个类来将元素固定到顶部。 我用来确定元素是否在视口(viewport)之外的函数是: i
我正在查询中创建一个弹出窗口。悬停时弹出窗口一切正常。当用户的鼠标离开 div 以关闭它时,我让它看到计时器启动。如果他在计时器完成之前再次进入 div,则计时器将被清除。 这很好,但是如果用户点击
我使用名为 zonemap 的字典创建了一个 4x6 区域 map 。我在该字典中嵌套了多个字典;每个区域代表玩家可以访问并与之互动的区域。我希望能够将玩家的移动限制在该 4x6 区域,并重新显示他们
我正在构建一个页面,该页面将使用 ajax 来更新主要内容区域。用户将单击左侧菜单栏中的项目来更新右侧的 div 并包含搜索结果。 我想检测用户是否向下滚动到目前为止导致右侧结果 div 移出视口(v
好的,我在 div 中有一个带有拖放类的表格,其溢出设置为“自动”,这允许我隐藏部分时间表,只在底部放置一个滚动条。但是,我只是在可滚动 div 之外创建了一些可放置元素,并且我的可拖动元素无法离开可
我有大量项目绑定(bind)到 ListBox,VirtualizingStackPanel 设置为它的 ItemsPanel。随着用户滚动和项目容器的创建,我做了一些工作来用数据填充项目(使用数据库
我想知道是否有一种方法可以将类成员的访问范围专门限定为在 C# 中获取/设置实现,以减少我意外直接访问它们的可能性。类似 private 的东西,但只允许 get/set 访问它,我想我可以将每个变量
我正在尝试编写一个小游戏,以应用我自己在本类(class)中学到的概念。当游戏打开时,我想要一个自定义模态视图来告诉用户如何玩。同样,当他们输了时,我想呈现一个结果页面,该页面将位于 if 语句内。我
我有一个非常具体的 HTML/CSS 和/或 JS 问题。我在 this fiddle here 创建了一个示例显示问题。 我有一个可滚动的 div,它是一个表的父级: ...我的表格行之一包
我的 jar 文件中打包了一个 exe,我试图将它复制到一个临时位置,以便我可以使用 Desktop.browse() 运行它,为此我设置了一个使用 class.getResourceAsStream
您好,我对这段代码有疑问。我的问题是第一个 console.log(smile_per_sec) 给了我需要的值,但是第二个给了我声明变量时给它的值。 $.getJSON( twitter
我必须更改标记弹出窗口的默认大小以容纳我想放入其中的数据。我更改了一些 map 设置,因此当用户将其拖出 View 时,它总是会弹回最大范围。我遇到的问题是,对于靠近边缘的标记,当它的弹出窗口打开时,
我是一名优秀的程序员,十分优秀!