【问题标题】:implementing add and iadd for custom class in python?在python中为自定义类实现add和iadd?
【发布时间】:2013-11-25 21:58:26
【问题描述】:

我正在编写一个 Queue 类,该类包含大多数操作的列表。但我不从list 转接,因为我不想提供所有list API's。我在下面粘贴了我的代码。 add 方法似乎工作正常,但 iadd 似乎出错了,它没有打印。 代码如下:

import copy
from iterator import Iterator
class Abstractstruc(object):
    def __init__(self):
        assert False
    def __str__(self):
        return "<%s: %s>" %(self.__class__.__name__,self.container)

class Queue(Abstractstruc,Iterator):

    def __init__(self,value=[]):
        self.container=[]
        self.size=0
        self.concat(value)

    def add(self, data):
            self.container.append(data)
    def __add__(self,other):
        return Queue(self.container + other.container)


    def __iadd__(self,other):
        for i in other.container:
            self.add(i)

    def  remove(self):
        self.container.pop(0)


    def peek(self):
        return self.container[0]


    def __getitem__(self,index):
        return self.container[index]


    def __iter__(self):
        return Iterator(self.container)

    def concat(self,value):
        for i in value:
            self.add(i)

    def __bool__(self):
        return len(self.container)>0

    def __len__(self):
        return len(self.container)


    def __deepcopy__(self,memo):
        return Queue(copy.deepcopy(self.container,memo))


if __name__=='__main__':
    q5 = Queue()
    q5.add("hello")

    q6 = Queue()
    q6.add("world")

    q5 = q5+q6

    print q5
    q5+=q6
    print q5    

输出:

<Queue: ['hello', 'world']>
None

【问题讨论】:

    标签: python class object add in-place


    【解决方案1】:

    就地添加时__iadd__需要返回self

    def __iadd__(self,other):
        for i in other.container:
            self.add(i)
        return self
    

    __iadd__需要返回结果对象;对于不可变类型,新对象,对于可变类型,self。引用in-place operator hooks documentation

    这些方法应该尝试就地执行操作(修改self)并返回结果(可以是,但不一定是self)。

    【讨论】:

    • 添加return self 有效。我以为我正在更改可变实例属性,所以我不必返回 self..就像我上面的 add 方法一样。在__add__ 的情况下,我正在返回一个新对象,因此需要返回。对于__iadd__,因为是in-place add,所以我有一种错误的印象,就是改变self的状态会直接体现出来。
    • @user1988876:如果您使用原来的+=,并保留对该对象的另一个引用以便检查它,您会发现它实际上正在改变原始对象,只是它将名称重新绑定到None。您希望它改变原始对象,并保持名称绑定到self
    • @abarnert 我不知道,谢谢!现在这更有意义了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-22
    • 1970-01-01
    • 2022-10-04
    • 2015-02-27
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    相关资源
    最近更新 更多