2012-02-29 79 views
3

全部, 正如标题所述,是否有可能在运行时更改描述符的方法__get__。我处于一种在运行时正在进行装饰和未装饰的功能的情况。我希望此功能的结果作为属性提供,与@property相似。我研究了它,发现它是一个描述符,但似乎描述符的方法是只读的。您可以在运行时更改Python描述符的__get__方法吗?

class Test(object): 
    def __init__(self): 
     self._x = 10 

    def get_x(self): 
     return self._x 

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

上面的代码我想要做什么,大致在

  1. 值在构造函数中设置
  2. 我可以装点get_x方法对我的心脏的内容
  3. instance.x回报正确的值

我的问题是,我宁愿不必因为它基本上是不必要的,因此创建get_x方法。我只是无法装饰x的__get__方法,因为它是只读的。

背景

我正在写一个回合策略游戏,和我使用的装饰来实现持续的条件。当我使用测试用例时,我能够有效地实现这些装饰器,但问题是要获得计算值,则必须使用函数调用,而不是属性访问。这似乎是一个糟糕的主意,因为获取描述单元的值会不一致地使用函数或属性。如果可以,我想标准化属性。

回答

4

您可以覆盖默认的“只读” property__get__属性的特性使用简单的继承:

class MyProperty(property): pass 

class Test(object): 
    def __init__(self): 
     self._x = 10 

    def get_x(self): 
     return self._x 

    @MyProperty 
    def x(self): 
     return self.get_x() 

test = Test() 

现在的问题是,即使你重新定义你的Text.x财产__get__ attribure,在test.x要求Python运行时会调用MyProperty.__get__(Test.x, test, Test)

所以,你可以重写它只有在那里像

MyProperty.__get__ = lambda self,instance,owner: ""the x attribute" 
这里

所以很好的选择是委托调用一些redifineable属性像

MyProperty.__get__ = lambda self,instance,owner: self.get(instance,owner) 

从现在起让你的财产的属性,在完全控制。 也有不好的选项为每个属性类对象生成单独的类型。 因此,在良好的情况下,你可以这样做:

class MyProperty(property): 
    def __get__(self,instance,owner) : 
     if not instance: return self 
     else: return self.get(instance,owner) 

class Test(object): 
    def __init__(self): 
     self._x = 10 

    def get_x(self): 
     return self._x 

    @MyProperty 
    def x(self): pass 

    @MyProperty 
    def y(self): pass 

    x.get = lambda self,clazz: self.get_x() 
    y.get = lambda self,clazz: "the y property of " + clazz.__name__ + " object" 

>>> test = Test() 
>>> test.x 
10 
>>> test.y 
'the y property of Test object' 
+0

谢谢,我会考虑这是今天,但它看起来像它做我想要的。如果一切正常,我会接受答案。 – mklauber 2012-02-29 15:45:50

相关问题