15
class A:
  @property
  def p(self): return 2

  def q(self): return 2

a = A()
A.p(a) #>> TypeError: 'property' object is not callable

A.q(a) #>> no error, returns 2

どうしてこれなの?インスタンスのプロパティを参照したかどうかはわかります。ap は単にメソッドの戻り値を返しますが、クラスのプロパティから始めようとしています。両方とも 2 と評価されるため、上記のエラーはないと予想していました。

4

3 に答える 3

19

の世界を掘り下げていますdescriptorsA.pは apropertyであり、プロパティは記述子です。これは、ディスクリプタがインスタンスでアクセスされたときに呼び出される魔法のメソッド ( __get__、 ...) を持つクラスです。アクセスされる特定のメソッドは、もちろんアクセス方法によって異なります。クラスの記述子にアクセスすると、単に記述子自体が返され、魔法は実行されません。この場合、記述子は呼び出し可能ではないため、エラーが発生します。__set__property

を呼び出すとどうなるか注意してください__get__:

class A(object):
    @property
    def p(self):  
        return 2

a = A()
print (A.p.__get__(a)) #2

foo = A.p.__get__(a)を実行すると、内部で実際に発生しますfoo = a.p。かなりスパイシーだと思います...

于 2012-11-13T21:28:13.743 に答える
7

プロパティは呼び出し可能ではないため:

In [3]: class A(object):
   ...:   @property
   ...:   def p(self): return 2
   ...:

In [4]: A.p
Out[4]: <property at 0x2d919a8>

In [5]: dir(A.p)
Out[5]:
['__class__',
 '__delattr__',
 '__delete__',
 '__doc__',
 '__format__',
 '__get__',
 '__getattribute__',
 '__hash__',
 '__init__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__set__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 'deleter',
 'fdel',
 'fget',
 'fset',
 'getter',
 'setter']

メソッドがないことに注意してください__call__。これは、プロパティが複数の関数をラップできるためです。

プロパティをインスタンスのメソッドとして呼び出そうとすると、次のようになります。

In [6]: a = A()

In [7]: a.p()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
C:\Users\Marcin\<ipython-input-7-16c8de382321> in <module>()
----> 1 a.p()

TypeError: 'int' object is not callable
于 2012-11-13T21:28:34.030 に答える
2

プロパティ デコレータはメソッドをプロパティに変換します。これはもはや関数オブジェクトではなく、property代わりに であるため、呼び出し可能ではありません

于 2012-11-13T21:27:32.443 に答える