下面是我的测试代码:
import functools
class LazyLoader(object):
def __init__(self, klass, *args, **kwargs):
self.klass = klass
self.args = args
self.kwargs = kwargs
self.instance = None
def __getattr__(self, name):
return functools.partial(self.__run_method, name)
def __run_method(self, __name, *args, **kwargs):
if self.instance is None:
self.instance = self.klass(*self.args, **self.kwargs)
return getattr(self.instance, __name)(*args, **kwargs)
class SchedulerReportClient(object):
def method(self):
print 'method called'
def __getattr__(self, name):
print '__getattr__ called'
return functools.partial(self.__run_method, name)
def __run_method(self, __name, *args, **kwargs):
print '__run_method called'
return getattr(self, __name)(*args, **kwargs)
if __name__ == "__main__":
a = SchedulerReportClient()
entity = LazyLoader(a)
print hasattr(entity, 'obj_to_primitive')
print(callable(entity.obj_to_primitive))
print entity.__class__.__name__
if hasattr(entity, 'obj_to_primitive') and callable(entity.obj_to_primitive):
entity.obj_to_primitive()
结果是:
True
True
Traceback (most recent call last):
LazyLoader
File "C:/Users/chen/PycharmProjects/pytest/main", line 42, in <module>
entity.obj_to_primitive()
File "C:/Users/chen/PycharmProjects/pytest/main", line 17, in __run_method
self.instance = self.klass(*self.args, **self.kwargs)
TypeError: 'SchedulerReportClient' object is not callable
代码大部分在openstack nova中,我复制了一些。
类obj_to_primitive
中没有SchedulerReportClient
方法,为什么hasattr和callable函数返回true?
具有Python2.7的CentOS7.4。
答案 0 :(得分:1)
内置函数hasattr
是通过调用getattr
并检查其是否引发异常来实现的。这在文档中有说明。
如果字符串是对象之一的名称,则结果为
True
属性,如果没有,则为False
。 (这是通过调用 getattr(object,name)并查看它是否引发异常或
在这种情况下,您定义了LazyLoader.__getattr__
方法,该方法返回部分评估的方法LazyLoader.__run_method
,而与参数name
的值无关。
def __getattr__(self, name):
return functools.partial(self.__run_method, name)
提醒一下,在通常情况下找不到属性时,将调用__getattr__
方法。
因此,当您获得entity.obj_to_primitive
时,将返回functools.partial(entity.__run_method, 'obj_to_primitive')
。