したがって、辞書型の値と遅延評価されたプロパティが混在するクラスを実装しようとしています。私は文法上、クラスから__getitem__
と__getattr__
経由でアイテムにアクセスし、同じ方法でそれらの値を設定することができますが、whenとsettersのプロパティを使用しています。プロパティを持つクラスの__getattr__と__setattr__メソッドをオーバーライドする
いくつかの私はこれを実装想定する方法のコード例:
class C(object):
def __init__(self):
self.data = {'akey':'avalue'}
self.att1 = '1st attribute'
self._prop1 = None
def __getitem__(self,key):
try:
self.__dict__[key]
except KeyError:
return self.data[key]
def __setitem__(self,key,val):
self.data[key] = val
def __getattr__(self,name):
try:
self.__dict__[name]
except KeyError:
return self.data[name]
def __setattr__(self,name,val):
try:
self.__dict__[name] = val
except KeyError:
self.data[name] = val
@property
def prop1(self):
#do expensive stuff here in real class
return self._prop1
@prop1.setter
def prop1(self,newval):
#check/change value for prop1
self._prop1 = str(newval).upper()
属性へのアクセスは、プロパティではなく__getitem__
方法のために正常に動作します。
In [35]: c = C()
In [36]: c.prop1
Out[36]: 'Prop1 Calc Value'
In [37]: c['prop1']
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
C:\Users\someuser\somepath\foo.py in __getitem__(self, key)
8 try:
----> 9 self.__dict__[key]
10 except KeyError:
KeyError: 'prop1'
During handling of the above exception, another exception occurred:
KeyError Traceback (most recent call last)
C:\Users\someuser\somepath\foo.py in <module>()
----> 1 c['prop1']
C:\Users\someuser\somepath\foo.py in __getitem__(self, key)
9 self.__dict__[key]
10 except KeyError:
---> 11 return self.data[key]
12
13 def __setitem__(self,key,val):
KeyError: 'prop1'
は、私は完全に@property
デコレータはクラスでどのように機能するかを理解していないためであると仮定したが、この問題を解決するための慣用的な方法がある場合、私はそれを聞くのが大好きです!私はそれが本当に構文的な砂糖だと知っていますが、クラスのための柔軟な属性アクセスを持っていて、有効なPython変数名ではないキーをサポートすることができればうれしいです。 pandas.DataFrame/collections.namedtuple apiはこれのインスピレーションです。次のコードは、私のシステム(のpython 3.5)上で動作し、正しい方向に私を指しているため@Jim Fasarakis・ヒリアードへ
Thansk:
編集
作業溶液
class C(object):
def __init__(self):
self.data = {'akey':'avalue'}
self.att1 = '1st attribute'
self._prop1 = None
def __getitem__(self,key):
try:
return self.__dict__[key]
except KeyError:
try:
return getattr(type(self), key).__get__(self)
except AttributeError:
return self.data[key]
__getattr__ = __getitem__
def __setitem__(self,key,value):
#note order is look for property 1st so that any
#setter methods get used insead of attribute access
try:
getattr(type(self), key).__set__(self,value)
except AttributeError:
try:
self.__dict__[key] = value
except KeyError:
self.data[key] = value
__setattr__ = __setitem__
@property
def prop1(self):
#do expensive stuff here in real class
if not self._prop1:
self._prop1='Prop1 Calc Value'
return self._prop1
@prop1.setter
def prop1(self,newval):
#check/change value for prop1
print('using setter')
self._prop1 = str(newval).upper()
In [62]: c = C()
In [63]: c['prop1']
Out[63]: 'Prop1 Calc Value'
In [64]: c['prop1'] = 'new value'
using setter
In [65]: c['prop1']
Out[65]: 'NEW VALUE'
In [66]: c.akey
Out[66]: 'avalue'
In [67]: c.att1
Out[67]: '1st attribute'
は私が前に言ったように、それは本当にです私はビルドしているモジュールのためのちょうど砂糖。 –
ありがとうゲッターのために働く。 2番目の 'except'を' except AttributeError'に変更する必要があります。私はセッターを仕掛けたと思う。最終的な実装で編集された質問 –