这是真的吗?
我在接下来的代码中遇到了困难。我想稍后在 execute()
调用中调用一些方法。但令人惊讶的是,当我调用 getattr(self,...)
时,Python 会调用默认方法 __getattr__
,而不是首先搜索方法 __m1 和 __m2。
class MyApi(object):
"Class with API."
def __init__(self):
self.methods = []
class Callable(object):
def __init__(self, obj, name):
self.obj = obj
self.name = name
def __call__(self, *args, **kwargs):
self.obj.methods.append((self.name, args, kwargs,))
def __m1(self, name):
print "m1: name is %s" % name
exit(0)
def __m2(self, *args, **kwargs):
print "m2: args is {} and kwargs is {}".format(args, kwargs)
exit(0)
def execute(self):
for meth in self.methods:
meth_name = '__' + meth[0]
print meth_name
getattr(self, meth_name)(*meth[1], **meth[2]) # it seems to call __getattr__, not existing __m1 and __m2
self.methods = []
def __getattr__(self, name):
return MyApi.Callable(self, name)
api = MyApi()
#import pdb; pdb.set_trace()
api.m1('Serg')
api.m2('John', 'Harrison', **{'key1': 1, 'key2': 2})
api.execute()
讨论的结果。
我们一致认为问题出在两个下划线中,它们隐藏了属性 __m1
和 __m2
。
最佳答案
来自docs :
Called when an attribute lookup has not found the attribute in the usual places (i.e. it is not an instance attribute nor is it found in the class tree for self). [...] Note that if the attribute is found through the normal mechanism,
__getattr__()
is not called.
所以不,正常情况下不应该调用它。
如果您在内部方法调用__getattr__
时遇到问题,您可以随时使用object.__getattr__(self, attr_name)
来使用Python的默认查找。
如果您确实遇到这样的问题,则可能是name mangling有问题。 dunder 名字。如果类属性以d双下分开头,Python将破坏该名称,以便从该类实例以外的任何内容进行访问。这包括 child 类!对“私有(private)”方法/属性使用单下划线,除非您确实需要该功能。
关于python - 即使属性存在,getattr() 是否总是调用现有的 __getattr__() ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33320838/