2009-06-23 9 views
1

私は私が戻って装飾されたオブジェクトを参照し、そこから別のデコレータをつかむことができますデコレータ、あなたがプロパティにセッター/デリータを使用することができます同じように作成したい:装飾されたオブジェクトのプロパティであるデコレータ?

@property 
def x(self): 
    return self._x 

@x.setter 
def x(self, y): 
    self._x = y 

具体的には、私がしたいです基本的にプロパティと同じように動作しますが、単一の値ではなくシーケンスをエミュレートします。ここでの私の最初のショットはだが、動作していないよう:

def listprop(indices): 
    def dec(func): 
     class c(object): 
      def __init__(self, l): 
       self.l = l 
      def __getitem__(self, i): 
       if not i in self.l: 
        raise Exception("Invalid item: " + i) 
       return func(i) 
      @staticmethod 
      def setter(func): 
       def set(self, i, val): 
        if not i in self.l: 
         raise Exception("Invalid item: " + i) 
        func(i, val) 
       c.__setitem__ = set 
     return c(indices) 
    return dec 

# ... 
class P: 
    @listprop(range(3)) 
    def prop(self, i): 
     return get_prop(i) 

    @prop.setter 
    def prop(self, i, val): 
     set_prop(i, val) 

私はc.__setitem__ = setが間違っていることをかなり確信しているが、私はその時にインスタンスへの参照を取得する方法を見つけ出すことはできませんポイント。アイデア?

アレックスマルテッリのソリューションは、2.6では動作するのですが、それについて何かが(それは厳密には必要ではないのですけれども、私は、それは同様にこれらの古いバージョンでは動作していことを好むだろう)2.4および2.5に失敗している:

2.4:

>>> p = P() 
>>> p.prop 
>>> p.prop[0] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in ? 
TypeError: unsubscriptable object 

2.5:

>>> p = P() 
>>> p.prop 
>>> p.prop[0] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: 'NoneType' object is unsubscriptable 

2.6:

>>> p = P() 
>>> p.prop 
<__main__.c object at 0x017F5730> 
>>> p.prop[0] 
0 
+0

単にプロパティの値をリストに設定するのはなぜですか? –

+0

@ S.Lott:リストは必要ないので、リストのように見えるが、リストインデックスを追加引数として使用して、実際には別の場所から値を取得する必要があります。実際には、私は非常に似ているが、わずかに異なることがいくつか必要です。 – Jorenko

答えて

3

私は多くのほとんどの詳細を固定して、次のバージョンは、あなたが必要として動作しているようです:

def listprop(indices): 
    def dec(func): 
     class c(object): 
      def __init__(self, l, obj=None): 
       self.l = l 
       self.obj = obj 
      def __get__(self, obj, cls=None): 
       return c(self.l, obj) 
      def __getitem__(self, i): 
       if not i in self.l: 
        raise Exception("Invalid item: " + i) 
       return func(self.obj, i) 
      def setter(self, sfunc): 
       def doset(self, i, val): 
        if not i in self.l: 
         raise Exception("Invalid item: " + i) 
        sfunc(self.obj, i, val) 
       c.__setitem__ = doset 
       return self 
     result = c(indices) 
     return result 
    return dec 

# ... 
class P: 
    @staticmethod 
    def get_prop(i): return i*100 

    @staticmethod 
    def set_prop(i, val): print 'set %s to %s' % (i, val) 

    @listprop(range(3)) 
    def prop(self, i): 
     return self.get_prop(i) 

    @prop.setter 
    def prop(self, i, val): 
     self.set_prop(i, val) 

ご覧のとおり、c.__setitem__に割り当てることは問題ではなかった - __get__を欠くCのような他の人が、ありました(したがって、記述子ではありませんでした。this guiideを参照してください)、setterはNoneを返します(したがって、p.propはNoneになりました)。

関連する問題