160

だから、私は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

getter を呼び出し、デフォルト値がなく、失敗するため、明らかに最初の呼び出しは期待どおりに機能します。わかりました。わかりました。ただし、割り当ての呼び出しt.x = 5は新しいプロパティを作成するようでx、ゲッターは機能しません!

私は何が欠けていますか?

4

4 に答える 4

319

Python 2 で従来の古いスタイルのクラスを使用しているようです。プロパティが正しく機能するためには、代わりに新しいスタイルのクラスを使用する必要があります (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
>>> 

問題を引き起こす可能性があるもう 1 つの詳細は、両方のメソッドが機能するために同じ名前のプロパティを必要とすることです。このように別の名前でセッターを定義すると、機能しません

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

最初は完全に見つけにくいもう 1 つのことは、順序です。getterを最初に定義する必要があります。最初にセッターを定義すると、 name 'x' is not definedエラーが発生します。

于 2009-02-28T14:43:40.770 に答える
24

オブジェクトからクラスを派生させることによって行う、新しいスタイルのクラスを使用する必要があります。

class testDec(object):
   ....

その後、動作するはずです。

于 2009-02-28T14:43:22.567 に答える
12

誰かがGoogleからここに来た場合、上記の回答に加えて、この回答__init__に基づいてクラスのメソッドからセッターを呼び出すときに注意が必要であることを追加したいと思います 具体的には:

class testDec(object):                                                                                                                                            

    def __init__(self, value):
        print 'We are in __init__'
        self.x = value # Will call the setter. Note just x here
        #self._x = value # Will not call the setter

    @property
    def x(self):
        print 'called getter'
        return self._x # Note the _x here

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

t = testDec(17)
print t.x 

Output:
We are in __init__
called setter
called getter
17
于 2015-02-11T21:23:33.210 に答える