2013-11-25 3 views
0

Я пишу класс Queue, который переносит список для большинства его операций. Но я не подшучиваю от list, так как я не хочу предоставлять все list API's. У меня есть мой код, вставленный ниже. Метод add, похоже, работает нормально, но iadd похоже идет не так, печатается нет. Вот код:реализация add и iadd для пользовательского класса в python?

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 

ответ

8

__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).

+0

с добавлением 'return self' works. Я думал, что меняю атрибут изменяемого экземпляра, поэтому мне не нужно возвращать себя ... так же, как мой метод «добавить» выше. в случае '__add__' я возвращаю новый объект, поэтому требуется возврат. для '__iadd__', так как это дополнение на месте, я был под неправильным впечатлением, что изменение состояния себя будет непосредственно отражать. –

+1

@ user1988876: Если вы используете свой оригинальный '+ =' и сохраняете другую ссылку на объект, чтобы вы могли его проверить, вы увидите, что он фактически _is_ мутирует исходный объект, это просто то, что он _also_ переименовывает имя в ' None'. Вы хотите, чтобы он исказил исходный объект, а также сохранил имя, связанное с 'self'. – abarnert

Смежные вопросы