是真的吗?
我在下一个代码中遇到了困难。我想稍后在execute()调用中调用一些方法。但令人惊讶的是,python在调用getattr(self,...)时调用默认方法getattr(self,...),而不是首先搜索方法__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。
发布于 2015-10-24 17:06:48
来自文档
当属性查找没有在通常的位置找到属性时调用(即它不是实例属性,也不是自定义的类树中的属性)。..。注意,如果通过正常机制找到该属性,则不会调用
__getattr__()。
所以不,在正常情况下不应该叫它。
如果内部方法调用__getattr__有问题,则可以始终使用object.__getattr__(self, attr_name)来使用python的默认查找。
如果您确实遇到了这样的问题,您可能会遇到名称残缺 of dunder的问题。如果类属性以_d_ouble _under_scores开头,python将从类的实例以外的任何地方破坏访问的名称。这包括儿童课程!对“私有”方法/属性使用单个下划线,除非您确实需要该功能。
发布于 2015-10-24 17:03:58
不是的。
如果存在属性,则不调用__getattr__。
当您想要这样的行为时,必须使用__getattribute__方法。
在我看来,您的问题是(正如MisterMiyagi正确地指出的),方法名为__m1和__m2 (顺便说:正确的名称是什么--在一个位置上,您在另一个__m1中称它为m1 --这是不一致的)将被系统破坏。也就是说,系统将它们看作是_<classname>__<methodname>或_MyApi__m1。因此,在使用"getattr“时,必须使用损坏的名称。
https://stackoverflow.com/questions/33320838
复制相似问题