1

私はpython記述子を理解しましたが、これについて少し混乱しています..

次のようなクラス記述子がある場合

class Descriptor(object):
    def __get__(self, instance, owner):
        print 'getting'
        return self.value
    def __set__(self, instance, value):
        print 'setting'
        self.value = value
    def __delete__(self, instance):
        print 'deleting'
        del self.value

そして、管理したい属性を持つクラスは、このようなものです..

class Test(object):
    name = Descriptor()
    def __init__(self, name):
        print 'init test'
        self.name = name

クラス Test のオブジェクトを作成して何かを行うと、次のような答えが得られます...

t = Test('abc')
init test
setting
>>> t.name
getting 
'abc'
>>> del t.name
deleting
>>> t
<__main__.Test object at 0x013FCCD0>
>>> t.name
getting 

今、私はクラス Test1 をこのようなものにしたいと思っています..

class Test1(object):
    def __init__(self, value):
        print 'init test1'
        self.name = Descriptor()
        self. value = value

そして、Test1 のオブジェクトを作成し、Test1 のインスタンスの属性にアクセスしようとすると、次のような出力が得られます..

t1 = Test1(12)
t1.name
>>> getting
>>> 12
>>> t1.name = 30
>>> setting

Q 1) 私の質問は、この名前属性が Test1 の init で宣言されているか、Test1 のインスタンスにバインドされているかどうかです... t1 の属性辞書を取得しようとすると、空の辞書が返されるためです...

t1.__dict__
>>> {}

クラス Test のインスタンス t についても同じ

 t.__dict__
 >>> {}

これらのインスタンスのいずれかに新しい属性を追加すると、次のようになります...

 t.some = 'some'
 >>> t1.some = 'some'

再び属性ディクショナリにアクセスしようとすると、今追加したものだけが表示されます..すべてのインスタンス属性

t.__dict__
>>> {'some': 'some'}
>>> t1.__dict__
>>> {'some': 'some'}

Q 2) init で定義されたインスタンス属性 (クラス Descriptor と Test の変数名と値など) とインスタンス作成後に定義された属性 (変数 t.some など) の違いは何ですか。

Q 3) クラス Test はクラス Test1 とどう違うのですか?

4

1 に答える 1

3

Test1あなたのは記述子として実際には使用されません。それDescriptorは と呼ばれる通常の属性nameであり、たまたまいくつかの特別なメソッドがあります。しかし、それはまだ記述子にはなりません。

記述子の呼び出し方法に関するドキュメントを読むと、記述子メソッドの呼び出しに使用されるメカニズムがわかります。あなたの場合、これはt.name次とほぼ同等であることを意味します。

type(t).__dict__['name'].__get__(t, type(t))

t1.name:

type(t1).__dict__['name'].__get__(t1, type(t1))

name__dict__インスタンスではなくクラスで検索されるため、違いは次のとおりです。Test1.__dict__という記述子がありません。name

>>> Test.__dict__['name']
<__main__.Descriptor object at 0x7f637a57bc90>
>>> Test1.__dict__['name']
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
KeyError: 'name'

また、考慮すべきことは、記述子がvalueそれ自体に属性を設定することです。つまり、のすべてのインスタンスがTest同じ値を共有します。

>>> t1 = Test(1)
init test
setting
>>> t2 = Test(2)
init test
setting
>>> t1.name
getting
2
>>> t2.name
getting
2
>>> t1.name = 0
setting
>>> t2.name
getting
0

実際にやりたいことは、の代わりにvalueonに設定することだと思います。これにより、 で期待される動作が得られます。instanceselfTest

于 2013-06-18T09:17:22.553 に答える