能否更改python描述符';运行时的s__get__方法?

能否更改python描述符';运行时的s__get__方法?,python,decorator,descriptor,Python,Decorator,Descriptor,全部,, 如标题所示,是否可以在运行时更改描述符的\uuuu get\uuuu方法。我所处的情况是,我有一个函数在运行时被动态地修饰和取消修饰。我希望此函数的结果可以作为属性使用,类似于@属性的功能。我研究了一下,发现它是一个描述符,但似乎描述符的\uuuu get\uuu方法是只读的 class Test( object ): def __init__( self ): self._x = 10 def get_x( self ): retur

全部,, 如标题所示,是否可以在运行时更改描述符的
\uuuu get\uuuu
方法。我所处的情况是,我有一个函数在运行时被动态地修饰和取消修饰。我希望此函数的结果可以作为属性使用,类似于
@属性
的功能。我研究了一下,发现它是一个描述符,但似乎描述符的
\uuuu get\uuu
方法是只读的

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的
    \uuuu get\uuu
    方法,因为它是只读的

    背景

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

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

    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属性的属性,在
    test.x
    request上,python运行时也会调用
    MyProperty

    所以你只能在那里重写

    MyProperty.__get__ = lambda self,instance,owner: ""the x attribute"
    
    所以这里最好的选择是将调用委托给一些可重定义的属性,比如

    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'
    

    谢谢,今晚我会调查一下的,不过看起来它符合我的要求。如果一切顺利,我会接受答案。