2012-12-18 2 views
1

У меня есть этот проект для колледжа, и я сталкиваюсь с несколькими ошибками в тестовом файле, предоставленном учителями.Методы Python (определяемые пользователем), возвращающие «builtins.AttributeError:« NoneType »»

Большинство из них связано с этим. Например, выполнив следующие действия:

caminho(posicao(0,0)).caminho_junta_posicao('este').caminho_origem() 

возвращается:

Traceback (most recent call last): 
    File "<string>", line 1, in <fragment> 
builtins.AttributeError: 'NoneType' object has no attribute 'caminho_origem' 

Однако, делая это:

c1 = caminho(posicao(0,0)) 
c1.caminho_junta_posicao('este') 
c1.caminho_origem() 

не возвращает никаких ошибок, но предполагаемую позицию.

И я не могу понять, почему это происходит. Bellow - это код, определяющий оба класса из примера, поскольку моя проблема с другими заключается в очень схожей. Любая помощь будет действительно оценена. Благодарю.

class posicao: 
    def __init__(self,l,c): 
     self.posicao=(l,c) 
    def posicao_linha(self): 
     return self.posicao[0] 
    def posicao_coluna(self): 
     return self.posicao[1] 
    def posicao_igual(self,p2): 
     return self.posicao[0] == p2.posicao_linha() and self.posicao[1]\ 
       == p2.posicao_coluna() 
    def posicao_relativa(self,d): 
     if d=='norte': 
      return posicao(self.posicao_linha()-1,self.posicao_coluna()) 
     elif d=='sul': 
      return posicao(self.posicao_linha()+1,self.posicao_coluna()) 
     elif d=='este': 
      return posicao(self.posicao_linha(),self.posicao_coluna()+1) 
     elif d=='oeste': 
      return posicao(self.posicao_linha(),self.posicao_coluna()-1) 




class caminho: 
    def __init__(self,p): 
     self.caminho = [p] 
    def caminho_junta_posicao(self,d): 
     p = self.caminho[-1] 
     self.caminho = self.caminho + [p.posicao_relativa(d)] 
    def caminho_origem(self): 
     return self.caminho[0] 
    def caminho_destino(self): 
     return self.caminho[-1] 
    def caminho_antes_destino(self): 
     return self.caminho[:-1] 
    def caminho_apos_origem(self): 
     return self.caminho[1:] 
    def caminho_comprimento(self): 
     return len(self.caminho) 
    def caminho_contem__ciclos(self): 
     for p in range(len(self.caminho)): 
      for p2 in self.caminho[p:]: 
       if p2.posicao_igual(self.caminho[p]): 
        return True 
     return False 
    def caminho_elimina_ciclos(self): 
     caminho = self.caminho 
     if self.caminho_contem_ciclos(): 
      for p in caminho: 
       for p2 in caminho[caminho.index(p):]: 
        if p.posicoes_iguas(p2): 
         caminho = caminho[:index(p)]+caminho[index(p2):] 
+2

Не могли бы вы опубликовать стенограмму, показывающую, что то, что вы сказали, происходит на самом деле? 'caminho_junta_posicao' действует на месте и ничего не возвращает, поэтому его нельзя сковать. В результате я не думаю 'c1 = c1.caminho_junta_posicao ('este'); c1.caminho_origem() 'мог работать, даже если вы это говорите. Возможно, вы имели в виду 'c1.caminho_junta_posicao ('este'); c1.caminho_origem() 'вместо? – DSM

+0

О, извините, вот что я имел в виду. Изменит вопрос. То, что вы сказали, означает, что мне нужно будет что-то вернуть? – Dusk252

+0

Пожалуйста, не редактируйте вопрос или, по крайней мере, не удаляйте оригинальные примеры. – taleinat

ответ

0

Этот метод:

def caminho_junta_posicao(self,d): 
    p = self.caminho[-1] 
    self.caminho = self.caminho + [p.posicao_relativa(d)] 

не явно return ничего, поэтому результатом вызова его является None. Поэтому

caminho(posicao(0,0)).caminho_junta_posicao('este') 

даст None и None не имеет метод caminho_origem(), следовательно, ваша ошибка.

Python условность, как правило, что методы, которые действуют на месте (как .append, .extend, а вот ваш .caminho_junta_posicao) возвращают None, что делает сцепление, как это невозможно. С другой стороны, он делает случайную модификацию исходного объекта в цепочке, которая, по вашему мнению, работает над копиями намного сложнее. Иногда привязка пригодится (см., Например, библиотеку pandas).

Я не рекомендую это делать, но если вы изменили метод, чтобы вернуть self в конец, т.е.

def caminho_junta_posicao(self,d): 
    p = self.caminho[-1] 
    self.caminho = self.caminho + [p.posicao_relativa(d)] 
    return self 

то результат caminho(posicao(0,0)).caminho_junta_posicao('este') бы ваш (теперь модифицированный) caminho объект, и вы могли бы приковать ее так, как вы пытались.

+0

Спасибо большое ^^ Все ответы были полезными, но ваш был самым подробным. Спасибо за помощь! Думаю, я узнал что-то новое с этим. – Dusk252

0

код вы предполагаете работать (но не) не работает, потому что ваш метод caminho_junta_posicao() не явно возвращать значение, что означает, что он не возвращает None, вызывая ошибку вы видите.

Код, который вы указали, работал (ваш второй пример), на самом деле не работал, когда я его попробовал (Python 3.1.3). - Я получил ту же ошибку, что и раньше.

Это как и ожидалось, поскольку поведение является последовательным.

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