我刚刚意识到所有用户定义的函数都有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
以达到相同的效果,或为什么它无效。
答案 0 :(得分:3)
您无法通过设置A.m.__get__
来执行此操作,因为在查找__get__
等特殊方法时,Python语言内部会跳过实例dict。 (例如,当您执行Foo
时,定义__repr__
方法的类type.__repr__
使用Foo.__repr__
代替repr(Foo)
。)