python动态函数名 python动态参数应用( 五 )


co = cat.sayHi.func_code
print co.co_argcount # 1
print co.co_names # ('name',)
print co.co_varnames # ('self',)
print co.co_flags0b100 # 0
2.9. 栈帧(frame)
栈帧表示程序运行时函数调用栈中的某一帧 。函数没有属性可以获取它,因为它在函数调用时才会产生,而生成器则是由函数调用返回的,所以有属性指向栈帧 。想要获得某个函数相关的栈?。?则必须在调用这个函数且这个函数尚未返回时获取 。你可以使用sys模块的_getframe()函数、或inspect模块的currentframe()函数获取当前栈帧 。这里列出来的属性全部是只读的 。
f_back: 调用栈的前一帧 。
f_code: 栈帧对应的code对象 。
f_locals: 用在当前栈帧时与内建函数locals()相同,但你可以先获取其他帧然后使用这个属性获取那个帧的locals() 。
f_globals: 用在当前栈帧时与内建函数globals()相同,但你可以先获取其他帧…… 。
def add(x, y=1):
f = inspect.currentframe()
print f.f_locals # same as locals()
print f.f_back # frame object at 0x...
return x+y
add(2)
2.10. 追踪(traceback)
追踪是在出现异常时用于回溯的对象,与栈帧相反 。由于异常时才会构建 , 而异常未捕获时会一直向外层栈帧抛出,所以需要使用try才能见到这个对象 。你可以使用sys模块的exc_info()函数获得它 , 这个函数返回一个元组,元素分别是异常类型、异常对象、追踪 。traceback的属性全部是只读的 。
tb_next: 追踪的下一个追踪对象 。
tb_frame: 当前追踪对应的栈帧 。
tb_lineno: 当前追踪的行号 。
def div(x, y):
try:
return x/y
except:
tb = sys.exc_info()[2] # return (exc_type, exc_value, traceback)
print tb
print tb.tb_lineno # "return x/y" 的行号
div(1, 0)
3. 使用inspect模块
inspect模块提供了一系列函数用于帮助使用自省 。下面仅列出较常用的一些函数,想获得全部的函数资料可以查看inspect模块的文档 。
3.1. 检查对象类型
is{module|class|function|method|builtin}(obj):
检查对象是否为模块、类、函数、方法、内建函数或方法 。
isroutine(obj):
用于检查对象是否为函数、方法、内建函数或方法等等可调用类型 。用这个方法会比多个is*()更方便,不过它的实现仍然是用了多个is*() 。
im = cat.sayHi
if inspect.isroutine(im):
im()
对于实现了__call__的类实例,这个方法会返回False 。如果目的是只要可以直接调用就需要是True的话,不妨使用isinstance(obj, collections.Callable)这种形式 。我也不知道为什么Callable会在collections模块中,抱歉!我猜大概是因为collections模块中包含了很多其他的ABC(Abstract Base Class)的缘故吧:)
3.2. 获取对象信息
getmembers(object[, predicate]):
这个方法是dir()的扩展版,它会将dir()找到的名字对应的属性一并返回,形如[(name, value), ...] 。另外,predicate是一个方法的引用,如果指定,则应当接受value作为参数并返回一个布尔值,如果为False,相应的属性将不会返回 。使用is*作为第二个参数可以过滤出指定类型的属性 。
getmodule(object):
还在为第2节中的__module__属性只返回字符串而遗憾吗?这个方法一定可以满足你,它返回object的定义所在的模块对象 。
get{file|sourcefile}(object):
获取object的定义所在的模块的文件名|源代码文件名(如果没有则返回None) 。用于内建的对象(内建模块、类、函数、方法)上时会抛出TypeError异常 。
get{source|sourcelines}(object):
获取object的定义的源代码,以字符串|字符串列表返回 。代码无法访问时会抛出IOError异常 。只能用于module/class/function/method/code/frame/traceack对象 。

推荐阅读