diveintopython.org
Python for experienced programmers

2.5. 使用 getattr 得到对象的各种引用

你已经知道Python函数是对象。你不知道的是,使用 getattr 函数,你可以得到一个直到运行时才知道的函数的引用。

例 2.12. getattr 介绍

>>> li = ["Larry", "Curly"]
>>> li.pop                       1
<built-in method pop of list object at 010DF884>
>>> getattr(li, "pop")           2
<built-in method pop of list object at 010DF884>
>>> getattr(li, "append")("Moe") 3
>>> li
["Larry", "Curly", "Moe"]
>>> getattr({}, "clear")         4
<built-in method clear of dictionary object at 00F113D4>
>>> getattr((), "pop")           5
Traceback (innermost last):
  File "<interactive input>", line 1, in ?
AttributeError: 'tuple' object has no attribute 'pop'
1

这样得到列表的 pop 方法的一个引用。注意这样不是调用 pop 方法,调用应是 li.pop()。它是方法本身。

2

这样也返回 pop 方法的引用,但这次,方法的名字被指定为 getattr 函数的一个字符串参数。 getattr 是一个相当有用的内置函数,它可以返回任意对象的任意属性。在本例中,对象是列表,属性是 pop 方法。

3

万一不是深信它是多么的有用,试试这个:getattr 的返回值方法,接着你可以调用它就好象直接调用 li.append("Moe")。但是你没有直接调用函数,而是把函数名当成字符串来指定。

4 getattr 也可以用于字典。
5

在理论上,getattr 应可以用于序列,除了序列没有方法,所以不管给出什么属性名, getattr 都将引发一个异常。

getattr 不只适用于内置数据类型。它也可用于模块。

例 2.13. getattr 用于 apihelper.py

>>> import odbchelper
>>> odbchelper.buildConnectionString             1
<function buildConnectionString at 00D18DD4>
>>> getattr(odbchelper, "buildConnectionString") 2
<function buildConnectionString at 00D18DD4>
>>> object = odbchelper
>>> method = "buildConnectionString"
>>> getattr(object, method)                      3
<function buildConnectionString at 00D18DD4>
>>> type(getattr(object, method))                4
<type 'function'>
>>> import types
>>> type(getattr(object, method)) == types.FunctionType
1
1

它返回在 odbchelper 模块中的 buildConnectionString 函数的引用, odbchelper 模块我们在开始了解Python中学过了。(你看到的16进制地址是专对我的机器的;你的输出将有所不同。)

2

使用 getattr,我们可以得到同一函数的同一引用。通常, getattr(object, "attribute") 相当于 object.attribute。如果 object 是一个模块,那么 attribute 可以是定义在模块中的任何东西:一个函数,类,或全局变量。

3 并且这个就是我们真正用在 help 函数中的东西。object 作为一个参数被传到函数中;method 是一个字符串,这个字符串是方法或函数的名字。
4 在本例中,method 是函数的名字,这一点我们可以通过得到它的类型来证实。