1. ホーム
  2. python

[解決済み] Pythonの@foo.setterが動作しないのはなぜですか?

2022-05-10 06:36:15

質問

Python 2.6でデコレータを使っているのですが、うまく動作させるのに苦労しています。以下は私のクラスファイルです。

class testDec:

    @property
    def x(self): 
        print 'called getter'
        return self._x

    @x.setter
    def x(self, value): 
        print 'called setter'
        self._x = value

これはどういう意味かというと x をプロパティのように扱い、get と set でこれらの関数を呼び出すことです。そこで、IDLEを起動して確認してみました。

>>> 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

明らかに最初の呼び出しは、ゲッターを呼び出すので、期待通りに動作し、デフォルト値はなく、失敗しています。OK、良いですね、理解できました。しかし、代入のための呼び出しは t.x = 5 を呼び出すと、新しいプロパティ x を作成するようで、ゲッターは動作しません!

何が足りないのでしょうか?

どのように解決するのですか?

あなたが使用しているようです を使用しているようですが、これは古いタイプのクラスです。 を使用しているようです。そのため プロパティを を正しく動作させるためには 新スタイルのクラス を使う必要があります (python 2 では を継承する必要があります。 object ). あなたのクラスを MyClass(object) :

class testDec(object):

    @property
    def x(self): 
        print 'called getter'
        return self._x

    @x.setter
    def x(self, value): 
        print 'called setter'
        self._x = value

動作します。

>>> k = testDec()
>>> k.x
called getter
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/devel/class_test.py", line 6, in x
    return self._x
AttributeError: 'testDec' object has no attribute '_x'
>>> k.x = 5
called setter
>>> k.x
called getter
5
>>> 

問題を引き起こすかもしれないもう一つの詳細は、両方のメソッドが動作するためにプロパティに同じ名前を必要とすることです。 このように異なる名前でセッターを定義すると、それは動作しません。 :

@x.setter
def x_setter(self, value):
    ...

そしてもう一つ、最初は完全に見抜けないのですが、順番です。ゲッターは が最初に定義されなければなりません。 . もしセッターを先に定義してしまうと name 'x' is not defined のエラーが発生します。