python找对象函数 python查询对象类型( 四 )


不要忘了函数也是对象,可以使用函数.属性名访问属性(赋值时如果属性不存在将新增一个),或使用内置函数has/get/setattr()访问 。不过,在函数中保存属性的意义并不大 。
func_defaults: 这个属性保存了函数的参数默认值元组;因为默认值总是靠后的参数才有,所以不使用字典的形式也是可以与参数对应上的 。
func_code: 这个属性指向一个该函数对应的code对象,code对象中定义了其他的一些特殊属性,将在下文中另外介绍 。
func_globals: 这个属性指向当前的全局命名空间而不是定义函数时的全局命名空间 , 用处不大,并且是只读的 。
*func_closure: 这个属性仅当函数是一个闭包时有效 , 指向一个保存了所引用到的外部函数的变量cell的元组,如果该函数不是一个内部函数 , 则始终为None 。这个属性也是只读的 。
下面的代码演示了func_closure:
#coding: UTF-8
def foo():
n = 1
def bar():
print n # 引用非全局的外部变量n,构造一个闭包
n = 2
return bar
closure = foo()
print closure.func_closure
# 使用dir()得知cell对象有一个cell_contents属性可以获得值
print closure.func_closure[0].cell_contents # 2
由这个例子可以看到,遇到未知的对象使用dir()是一个很好的主意 :)
2.6. 方法(method)
方法虽然不是函数 , 但可以理解为在函数外面加了一层外壳;拿到方法里实际的函数以后,就可以使用2.5节的属性了 。
__doc__: 与函数相同 。
__name__: 与函数相同 。
*__module__: 与函数相同 。
im_func: 使用这个属性可以拿到方法里实际的函数对象的引用 。另外如果是2.6以上的版本,还可以使用属性名__func__ 。
im_self: 如果是绑定的(bound),则指向调用该方法的类(如果是类方法)或实例(如果是实例方法),否则为None 。如果是2.6以上的版本,还可以使用属性名__self__ 。
im_class: 实际调用该方法的类,或实际调用该方法的实例的类 。注意不是方法的定义所在的类,如果有继承关系的话 。
im = cat.sayHi
print im.im_func
print im.im_self # cat
print im.im_class # Cat
这里讨论的是一般的实例方法,另外还有两种特殊的方法分别是类方法(classmethod)和静态方法(staticmethod) 。类方法还是方法,不过因为需要使用类名调用,所以他始终是绑定的;而静态方法可以看成是在类的命名空间里的函数(需要使用类名调用的函数) , 它只能使用函数的属性,不能使用方法的属性 。
2.7. 生成器(generator)
生成器是调用一个生成器函数(generator function)返回的对象,多用于集合对象的迭代 。
__iter__: 仅仅是一个可迭代的标记 。
gi_code: 生成器对应的code对象 。
gi_frame: 生成器对应的frame对象 。
gi_running: 生成器函数是否在执行 。生成器函数在yield以后、执行yield的下一行代码前处于frozen状态,此时这个属性的值为0 。
next|close|send|throw: 这是几个可调用的方法 , 并不包含元数据信息,如何使用可以查看生成器的相关文档 。
def gen():
for n in xrange(5):
yield n
g = gen()
print g # generator object gen at 0x...
print g.gi_code # code object gen at 0x...
print g.gi_frame # frame object at 0x...
print g.gi_running # 0
print g.next() # 0
print g.next() # 1
for n in g:
print n, # 2 3 4
接下来讨论的是几个不常用到的内置对象类型 。这些类型在正常的编码过程中应该很少接触,除非你正在自己实现一个解释器或开发环境之类 。所以这里只列出一部分属性 , 如果需要一份完整的属性表或想进一步了解,可以查看文末列出的参考文档 。

推荐阅读