リストを使用して一連の記述子を参照しようとしましたが、成功しませんでした。記述子 ( ) を介してアクセスしたい_b
外部ライブラリ ( ) によって定義されたオブジェクト ( ) のリストがあります。次の例では、記述子への参照のリストが割り当てられますが、リストのいずれかの項目に値が割り当てられると、記述子への参照は値を記述子に渡す代わりに、値によって上書きされます。記述子に関するいくつかの参考文献や記事を読んだ後でも、記述子の基本的な動作が明らかに欠けています。class A
class Descriptor
b
class Descriptor(object):
def __init__(self, varname):
self.varname = varname
pass
def __get__(self, instance, owner):
print('get', self.varname)
#return getattr(getattr(instance, self.varname),"get")()
return instance.__dict__[self.varname].get()
def __set__(self, instance, value):
print('set', self.varname)
#getattr(getattr(instance, self.varname),"set")(value)
instance.__dict__[self.varname].set(value)
class A(object):
def __init__(self, value=None):
self.value = value
def get(self):
return self.value
def set(self, value):
self.value = value
class C(object):
print "root"
a = Descriptor('_a')
b = [Descriptor('_b[x]') for x in range(5)]
def __init__(self, val):
print "init"
self._a = A()
self.a = val
self._b = [A() for x in range(5)]
self.b[0] = 1
c = C(3)
d = C(4)
print c._a.get()
print c.a
print d._a.get()
print d.a
print c.b[0]
私の実際のプログラムでは、外部ライブラリは、さまざまなインターフェイスを簡単に交換できるように抽象化したい gui ライブラリです。GUI のいくつかのビューには、プログラムのリストに対応するエントリ ボックスの列 (列ごとに最大 40 個) が含まれています。
また、ディスクリプタに渡されたインスタンス オブジェクトのメンバ関数にアクセスする方法としては、getattr
または__dict__
. __dict__
よりきれいに見えますが、それを使用する際にフレームワークや使いやすさの問題があるかどうかはわかりませんでした.
尋ねられた質問に関するヘルプや、プログラムでの私のニーズを満たすための他のアプローチの提案をいただければ幸いです。ありがとう。
ミリムースの推奨に従って、次のリストのようなクラスが私のニーズを満たしているようです。クラスルートで定義されている記述子以外のこのメソッドの落とし穴はあり__init__
ますか? 他のリスト関数を追加する必要があり、負のインデックスなどの特別なインデックス動作を追加する必要があります。
class DescriptorList(object):
def __init__(self, owner, varname):
self.owner = owner
self.varname = varname
def __getitem__(self, index):
print('getitem', self.varname, index)
return getattr(getattr(self.owner, self.varname)[index],"get")()
def __setitem__(self, index, value):
print('setitem', self.varname, index)
getattr(getattr(self.owner, self.varname)[index],"set")(value)
class C(object):
a = Descriptor('_a')
def __init__(self, val):
self._a = A()
self.a = val
self._b = [A() for x in range(5)]
self.b = DescriptorList(self, '_b')
for i in range(5):
self.b[i] = i
c = C(3)
print [c.b[i] for i in range(5)]
また、 でDescriptorList
インスタンス化すると、 がオブジェクトの名前の代わりにオブジェクト自体を使用するC.__init__
ように、コードを単純化できます。DescriptorList
この方法に利点または欠点はありますか?
class DescriptorList(object):
def __init__(self, var):
self.var = var
def __getitem__(self, index):
print('get', self.var, index)
return self.var[index].get()
def __setitem__(self, index, value):
print('set', self.var, index)
self.var[index].set(value)
class C(object):
a = Descriptor('_a')
def __init__(self, val):
self._a = A()
self.a = val
self._b = [A() for x in range(5)]
self.b = DescriptorList(self._b)
for i in range(5):
self.b[i] = i
__get__
と の扱いがと と異なる__set__
のはなぜですか?__getitem__
__setitem__