所有, 正如标题所问,是否可以在运行时更改描述符的
__get__
方法。我所处的情况是,我有一个在运行时动态装饰和未装饰的函数。我希望此函数的结果可作为属性使用,类似于 @property
的作用。我研究了一下,发现它是一个描述符,但似乎描述符的 __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()
上面的代码大致实现了我想要的功能
get_x
方法instance.x
返回正确的值我的问题是我不想创建
get_x
方法,因为它基本上是不必要的。我只是无法装饰 x 的 __get__
方法,因为它是只读的。
背景
我正在编写一个回合制策略游戏,并且我正在使用装饰器来实现持久条件。当我使用测试用例时,我能够有效地实现这些装饰器,但问题是要获取计算值,您必须使用函数调用,而不是属性访问。这似乎是一个坏主意,因为获取描述单元的值会不一致地使用函数或属性。如果可以的话,我想对属性进行标准化。
您可以使用简单的继承来覆盖
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()
现在的问题是,即使你重新定义了
__get__
属性的 Text.x
属性,在 test.x
请求上,Python 运行时也会调用 MyProperty.__get__(Test.x, test, Test)
所以你只能在那里重写它,例如:
MyProperty.__get__ = lambda self,instance,owner: "the x attribute"
这里很好的选择是将调用委托给一些可重新定义的属性,例如:
MyProperty.__get__ = lambda self,instance,owner: self.get(instance,owner)
从现在开始get您的财产属性由您完全控制。 另外,为每个类似属性的对象生成单独的类型也是一个不好的选择。 所以在好的情况下你可以这样做:
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'