2

次のコードで 2 つの異なる出力が得られる理由がわかりません

class foo(object):

       def myget(self):
          return 3

       goo=property(myget)

       hh1=[1,2,3]
       hh1[0]=property(myget)

       def hh(self):
         print self.goo
         print self.hh1[0]
ff=foo()
ff.hh()       

出力:

 3
 <property object at 0x292a998>

ありがとう

4

2 に答える 2

1

propertyオブジェクトは記述子です。記述子は、クラスにバインドされている場合にのみ特別な権限を持ちます。それ以外の場合は、他のクラスとまったく同じように動作します。プロパティをリストに入れると、クラスにバインドされないため、その特別なプロパティが失われます。


例として、記述子としてproperty 純粋な pythonで記述された の実装を見てみましょう。

class Property(object):
    "Emulate PyProperty_Type() in Objects/descrobject.c"

    def __init__(self, fget=None, fset=None, fdel=None, doc=None):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel
        self.__doc__ = doc

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        if self.fget is None:
            raise AttributeError, "unreadable attribute"
        return self.fget(obj)

    def __set__(self, obj, value):
        if self.fset is None:
            raise AttributeError, "can't set attribute"
        self.fset(obj, value)

    def __delete__(self, obj):
        if self.fdel is None:
            raise AttributeError, "can't delete attribute"
        self.fdel(obj)

との 2 番目の引数が obj __get__であることに注意してください。記述子がバインドされているクラスのインスタンスです (物事を明確にするのに役立つかのようにメソッドに渡されます)。シバン全体が機能するためには、記述子をクラスにバインドして、呼び出して渡すことができるようにする必要があります。記述子がクラスにバインドされていない場合、 は呼び出されず、記述子クラスは、(明示的に呼び出さない限り) 決して呼び出されないいくつかの魔法のメソッドを持つ単なる別のクラスになります。__set____delete__objself__get__obj__get__

もう少し具体的に言うと、次のようになります。

a = instance.my_descriptor

これはmy_descriptor.__get__(instance)、それに応じて次のように呼び出します。

instance.my_descriptor = a

通話my_descriptor.__set__(instance,a)

ただし、my_descriptorクラスにバインドされていない場合は、表示内容を説明する他のクラス (オブジェクト) と同じように動作します。

于 2012-10-10T01:13:56.833 に答える
0

私はそれがdictに関連しているかもしれないと思います。記述子(プロパティ)は、オブジェクトまたはクラスdict内の属性にのみ応答します。hh1[]とgooはどちらもfooにあります。dict。ただし、hh1 [0]は機能しないため、記述子はhh1[0]では機能しません。

于 2012-10-12T03:02:24.070 に答える