0

記述子を定義すると、値の取得などがオーバーライドされ、記述子のインスタンスに事実上アクセスできなくなります。

つまり、書くことはできませんinstance_with_descriptor_attr.descriptor_attr.some_method_on_descriptor()...動作しません。私の質問は、基本的に、どのようにして記述子のインスタンスにアクセスできるかということです...

4

3 に答える 3

4

eryksunが指摘しているように、Martijnのソリューションはプロパティに対して機能しますが、すべての記述子に対して機能するわけではありません。

class Desc(object):
    def __init__(self, val=None):
        self.val = val

    def __get__(self, obj, cls):
        return self.val

    def __set__(self, obj, val):
        self.val = val

class Test(object):
    x = Desc(5)

>>> o = Test()
>>> print o.x
5
>>> print Test.x
5

プロパティ記述子で機能する理由は、ドキュメントのプロパティ記述子の実装例で確認できます:http: //docs.python.org/2/howto/descriptor.html#properties

重要なのは__get__機能です。

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)

objがNoneの場合、記述子自体のインスタンスであるselfを返します。objは、記述子にアクセスするクラスのインスタンスです。クラスインスタンスから属性にアクセスする場合、objはそのインスタンスであり、クラスオブジェクトから属性にアクセスする場合、objはNoneです。

前の記述子を次のように変更します。

class Desc(object):
    def __init__(self, val=None):
        self.val = val

    def __get__(self, obj, cls):
        if obj is None:
            return self
        return self.val

    def __set__(self, obj, val):
        self.val = val

class Test(object):
    x = Desc(5)

イールド(Pythonシェルを使用している場合は、クラスを再定義する必要があります)

o = Test()
>>> print o.x
5
>>> print Test.x
<__main__.Desc object at 0x23205d0>
于 2013-02-15T03:54:11.127 に答える
1

あなたはクラス自体に行く必要があります:

type(instance_with_descriptor_attr).descriptor_attr

デモンストレーション:

>>> class Foo():
...     @property
...     def bar(self): return 'bar'
... 
>>> foo = Foo()
>>> foo.bar
'bar'
>>> type(foo).bar
<property object at 0x109f24310>
于 2012-11-20T15:08:45.443 に答える
0

__get__記述子のメソッドに""ステートメントがない場合、記述子にはクラスの属性return selfによってのみアクセスできます。__dict__

class descriptor:
    def __get__(self, instance, owner=None):
        return 1

class A:
    d = descriptor()

a = A()
a.d # --> 1
A.d # --> 1
A.__dict__['d'] # --> <__main__.descriptor object at ...>
于 2021-10-10T17:39:39.650 に答える