如果所有python方法确实都是非数据描述符,我可以覆盖一个方法.__ get__?

时间:2016-04-22 22:29:44

标签: python

我刚刚意识到所有用户定义的函数都有app.setProperty("username", "Eric"); ,当函数在类中使用时,它允许函数作为描述符运行。当在实例(__get__)的上下文中调用时,此__get__返回<bound method object>,并在类(myinstance.method)的上下文中调用时返回原始函数。

我试图让方法表现得像属性一样(与MyClass.method的方式相同,但没有数据描述符的副作用,即不能从实例覆盖)。我成功创建了一个非数据描述符,它只调用@property上的原始方法,但是当我发现函数已经是描述符时,我试图改变函数的__get__来直接进行调用,而不是返回一个__get__但没有运气。

这是我的尝试:

<bound method ...>

这没有达到预期的效果class A(object): def m(self): self.m = 20 # to show that .m is overridable at instance level return 10 def alternative__get(self, instance, owner): if instance is None: return self else: return self.__func__(instance) print(A.__dict__['m'].__get__) # => <method-wrapper '__get__' of function object ...> A.__dict__['m'].__get__ = alternative__get print(A.__dict__['m']) # <function m ..> print(A.__dict__['m'].__get__) # <function alternative__get ...> print(A.m) # <unbound method A.m> a = A() print(a.m) # <bound method A.m of ...> print(a.m) # <bound method A.m of ...> 仍然会解析为a.m,而不是直接返回调用<bound method...>的结果。

我目前的方法是定义一个描述符:

A.m(a)

这种方法有效,但我想知道是否可以更改class attribute(object): def __init__(self, fget): self.fget = fget def __get__(self, instance, owner): if instance is None: return self else: return self.fget(instance) class A(object): def __init__(self): pass @attribute def m(self): self.m = 20; return 10 a = A() print(a.m) # => 10 # a.m = 30 print(a.m) # => 20 because it's overriden at instance level 以达到相同的效果,或为什么它无效。

1 个答案:

答案 0 :(得分:3)

您无法通过设置A.m.__get__来执行此操作,因为在查找__get__等特殊方法时,Python语言内部会跳过实例dict。 (例如,当您执行Foo时,定义__repr__方法的类type.__repr__使用Foo.__repr__代替repr(Foo)。)