getattr 是一个相当有用的内置函数,用于返回一个对象属性,或者方法。许多人将 python 中的 getattr 称之为反射,这种方法在 python 的一些库及模块中很常见,我使用过的,如在 SocketServer 模块中必须定义 handle 方法,其就是使用反射进行调用的,还有在 django 的中间件中(request -> views –> exception -> reponse) ,这几个方法都是使用反射调用的,此方法的用处非常多,也比较灵活。
先看下官方对此方法的解释:
In [12]: getattr?? Docstring: getattr(object, name[, default]) -> value Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y. When a default argument is given, it is returned when the attribute doesn't exist; without it, an exception is raised in that case. Type: builtin_function_or_method
参数说明:
object:对象的实例
name:字符串,对象的成员函数的名字或者成员变量
default:当对象中没有该属性时,返回的默认值
异常:当没有该属性并且没有默认的返回值时,抛出”AttrbuteError”
先看一个例子帮你简单理解下反射:
In [24]: import os In [25]: s = "version" In [26]: getattr(os.sys,s) Out[26]: '2.7.10 (default, Nov 20 2015, 12:17:54) \n[GCC 4.4.7 20120313 (Red Hat 4.4.7-16)]'
getattr 可以将字符串作为一个方法进行执行,getattr(os.sys,s) 相当于执行了 os.sys.version 。
getattr 在类中的用法:
#!/usr/bin/env python # coding=utf-8 class demo(object): def __init__(self): self.name = 'feiyu' def name(self): print 'a is a method' def method(self): print 'method print' a = demo() print getattr(a, 'name', 'default') [root@sta tmp]# python test.py feiyu
从结果中可以看到 getattr 执行了类中的 name 属性,name 方法并没有执行。
#!/usr/bin/env python # coding=utf-8 class demo(object): def __init__(self): pass #self.name = 'feiyu' def name(self): print 'a is a method' def method(self): print 'method print' a = demo() print getattr(a, 'name', 'default') [root@sta tmp]# python test.py <bound method demo.name of <__main__.demo object at 0x7f36c4871c90>>
对比以上两个示例,getattr 会先查找该类的属性,如果没有相关的属性,然后再去查找是否有相关的方法,如果有则执行没有则报 AttributeError 错误。
In [7]: class demo(object): ...: name = 'feiyu' ...: def __getattr__(self, name): ...: print name, 'in getattr' ...: In [9]: a = demo() In [10]: a.name Out[10]: 'feiyu' In [11]: a.age age in getattr
当 getattr 方法显示定义在类中时,执行类的某些属性和方法找不到时,会调用此方法。
总结:getattr 多用于将类的某些方法作为字符串当做参数进行传递,然后使用 getattr 获取其返回结果。