Então, estou brincando com os decoradores no Python 2.6 e estou tendo alguns problemas para fazê-los funcionar. Aqui está o meu arquivo de classe:
class testDec:
@property
def x(self):
print 'called getter'
return self._x
@x.setter
def x(self, value):
print 'called setter'
self._x = value
O que eu pensei que isso significava é tratar x
como uma propriedade, mas chame essas funções de get e set. Então, iniciei o IDLE e verifiquei:
>>> from testDec import testDec
from testDec import testDec
>>> t = testDec()
t = testDec()
>>> t.x
t.x
called getter
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "testDec.py", line 18, in x
return self._x
AttributeError: testDec instance has no attribute '_x'
>>> t.x = 5
t.x = 5
>>> t.x
t.x
5
Claramente, a primeira chamada funciona como esperado, desde que eu chamo o getter, e não há valor padrão, e ele falha. OK, bom, eu entendo. No entanto, a chamada para atribuir t.x = 5
parece criar uma nova propriedade x
e agora o getter não funciona!
o que estou perdendo?
Respostas:
Parece que você está usando classes clássicas de estilo antigo no python 2. Para que as propriedades funcionem corretamente, você precisa usar classes de estilo novo (no python 2 você deve herdar
object
). Apenas declare sua classe comoMyClass(object)
:Funciona:
Outro detalhe que pode causar problemas é que os dois métodos precisam do mesmo nome para que a propriedade funcione. Se você definir o setter com um nome diferente como este, não funcionará :
E mais uma coisa que não é completamente fácil de identificar a princípio, é a ordem: o getter deve ser definido primeiro . Se você definir o setter primeiro, obtém
name 'x' is not defined
erro.fonte
Apenas uma observação para outras pessoas que tropeçam aqui procurando por essa exceção: ambas as funções precisam ter o mesmo nome. Nomear os métodos da seguinte maneira resultará em uma exceção:
Em vez disso, dê a ambos os métodos o mesmo nome
Também é importante observar que a ordem da declaração é importante. O getter deve ser definido antes do setter no arquivo, ou você receberá uma
NameError: name 'x' is not defined
fonte
NameError: name 'x' is not defined
exceção.Você precisa usar classes de novo estilo, derivando sua classe do objeto:
Então deve funcionar.
fonte
Caso alguém venha aqui do google, além das respostas acima, gostaria de acrescentar que isso precisa de muita atenção ao chamar o setter do
__init__
método da sua classe com base nesta resposta Especificamente:fonte
__init__
método, mas de qualquer outro método da classe.