gpt4 book ai didi

python - 为什么 "__iadd__"在与 "__getitem__"和 "__getattr__"一起使用时表现不同

转载 作者:行者123 更新时间:2023-12-02 15:53:20 26 4
gpt4 key购买 nike

使用以下代码:

class X( object ):

def __init__( self ):
self.value = 0

def __iadd__( self, value ):
self.value += value
return self

class Y( object ):

def __init__( self ):
self.fields = { 'test': X() }

def __getitem__( self, key ):
return( self.fields[ key ] )

def __getattr__( self, key ):
return self.fields[ key ]

obj = Y()

obj.test += 1

print( obj.test.value )

obj['test'] += 1

print( obj.test.value )

__iadd____getattr__ 一起使用会起作用,但是在使用 __getitem__ 时会出现错误:

TypeError: 'Y' object does not support item assignment

发生。

我知道 __iadd__ 实际上是 x = x.__iadd__(y),但是我不知道为什么它不能与 __getitem__ 一起使用

谢谢。

最佳答案

obj.test += 1 工作的原因是 obj.__setattr__ 有一个允许它工作的默认实现(虽然可能不是你想要的方式工作)——即,它在实例字典中存储对返回的 X 对象的引用。您可以通过以下方式观看它的发生:

>>> obj = Y()
>>> obj.test
<__main__.X object at 0x0000024BF247B220>
>>> obj.__dict__
{'fields': {'test': <__main__.X object at 0x0000024BF247B220>}}
>>> obj.test += 1
>>> obj.__dict__
{'fields': {'test': <__main__.X object at 0x0000024BF247B220>}, 'test': <__main__.X object at 0x0000024BF247B220>}

请注意,现在有一个 test 属性 在您的 fields 字典之外!两个字典都指向的仍然只有一个 X 对象(因为你的 __iadd__ 返回了 self,没有新的 X 曾经被创造过)。

当你执行 obj.test += 1 时,发生的事情是:

obj.__setattr__("test", obj.__getattr__("test").__iadd__(1))

__setattr__ 调用在 obj.__dict__ 中创建新的“测试”条目。

相反,当您执行 obj["test"] += 1 时,这将转化为:

obj.__setitem__("test", obj.__getitem__("test").__iadd__(1))

__setitem__ 引发了异常——与 __setattr__ 不同,没有默认的 object.__setitem__ 允许 obj[ "test"] = obj["test"] + 1 开始工作。

关于python - 为什么 "__iadd__"在与 "__getitem__"和 "__getattr__"一起使用时表现不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71858949/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com