为什么 a^=b 会抛出错误,而 a=a^b 不会?

问题描述 投票:0回答:2

My class' xor 函数按预期工作,但在执行 a^=b 时,我收到“TypeError: ^= 不支持的操作数类型:'NoneType' 和 'Multiset'”。相关代码如下:

def __xor__(self,o):
    d=Multiset() #subclass of dict
    for x in self|o: #for each item in both multisets
        m=abs((self[x] if x in self else 0) - (o[x] if x in o else 0)) #determines absolute difference of multiplicities of each element
        if m>0:
            d.add(x,m) #adds item x with multiplicity m to d
    return d

def __ixor__(self,o):
    self=self^o

我已经确认 a^b 返回 Multiset 并且设置 a=a^b 不会引发错误。我尝试注释掉 ixor 定义并重写如下:

def __ixor__(self,o):
    buffer=self^o
    self=buffer

此时,我几乎不知道问题出在哪里。

python operator-overloading multiset
2个回答
1
投票

您遇到的问题似乎与您尝试在班级中实现

__ixor__
方法有关。

问题在于

self = buffer
方法内的赋值
__ixor__
。在 Python 中,当您执行像
self = buffer
这样的赋值时,实际上是将局部变量
self
重新绑定到一个新对象(在本例中为
buffer
对象)。但是,这不会修改实例本身,这就是为什么您在方法之外看不到预期的更改。

要正确实现

__ixor__
方法,您需要修改实例本身的属性以反映XOR操作所做的更改。这是更正后的实现:

def __ixor__(self, o):
    result = self ^ o  # Calculate the XOR result using __xor__
    self.clear()  # Clear the current instance
    self.update(result)  # Update the instance with the new result
    return self  # Return the modified instance

在此实现中,我们首先使用

__xor__
方法计算异或结果。然后,我们使用
clear
方法清除当前实例(假设
Multiset
有此方法)以删除所有现有项目。最后,我们使用
update
方法用新结果更新实例。

通过最后返回

self
,我们确保该方法符合就地操作的预期行为,并且实例已正确修改。

请记住,应根据

self.clear()
类中可用的方法使用
self.update()
Multiset
。如果
Multiset
没有这些方法,您需要相应地调整实现以删除现有项目并添加新项目。


1
投票

您必须在就地操作中返回对象本身

只是:

def __ixor__(self,o):
    self=self^o
    return self
© www.soinside.com 2019 - 2024. All rights reserved.