Python函数信息

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

Python函数func的信息可以通过func.func_*和func.func_code来获取

一、先看看它们的应用吧:

1.获取原函数名称:

1 >>>def yes():pass23 >>> a=yes4 >>>a.func_name5'yes'6 >>>

2.获取函数的flags【后面有用,先说这个】

[python docs]:The following flag bits are defined forco_flags: bit0x04is set if the function uses the*argumentssyntax to accept an arbitrary number of positional arguments; bit0x08is set if the function uses the**keyWordssyntax to accept arbitrary keyword arguments; bit0x20is set if the function is a generator.

由这段Python官方文档可知,函数的flags与参数的定义方式有关,看看下面的试验:

>>>def yes():pass

>>>yes.func_code.co_flags

67

>>>def yes(a):pass

>>>yes.func_code.co_flags

67

>>>def yes(a,b=3):pass

>>>yes.func_code.co_flags

67

>>>def yes(*args):pass

>>>yes.func_code.co_flags

71

>>>def yes(a,*args):pass

>>>yes.func_code.co_flags

71

>>>def yes(a,b=32,*args):pass

>>>yes.func_code.co_flags

71

>>>def yes(*args,**kw):pass

>>>yes.func_code.co_flags

79

>>>def yes(a,*args,**kw):pass

>>>yes.func_code.co_flags

79

>>>def yes(a,b=3,*args,**kw):pass

>>>yes.func_code.co_flags

79

>>>def yes(**kw):pass

>>>yes.func_code.co_flags

75

>>>def yes(a,**kw):pass

>>>yes.func_code.co_flags

75

>>>def yes(a,b=1,**kw):pass

>>>yes.func_code.co_flags

75

>>>

>>> yes=(xfor xin range(100))

>>>yes

<generator object <genexPR> at 0x0000000002FF22D0>

>>> [xfor xin dir(yes)ifnot x.startswith('_')]

['close','gi_code','gi_frame','gi_running','next','send','throw']

>>>dir(yes)

['__class__','__delattr__','__doc__','__format__','__getattribute__','__hash__','__init__','__iter__','__name__','__new__','__reduce__','__reduce_ex__','__repr__','__setattr__','__sizeof__','__str__','__subclasshook__','close','gi_code','gi_frame','gi_running','next','send','throw']

>>>dir(yes.gi_code)

['__class__','__cmp__','__delattr__','__doc__','__eq__','__format__','__ge__','__getattribute__','__gt__','__hash__','__init__','__le__','__lt__','__ne__','__new__','__reduce__','__reduce_ex__','__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames']

>>> [x for x in dir(yes.gi_code) if x.startswith('co_')]

['co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames']

>>> yes.gi_code.co_flags

99

>>> yes.next()

0

>>> yes.next()

1

>>> yes.gi_code.co_varnames

('.0', 'x')

>>> for name in [x for x in dir(yes.gi_code) if x.startswith('co_')]:

print 'yes.gi_code.%s = %r'%(name,eval('yes.gi_code.%s'%name))

yes.gi_code.co_argcount = 1

yes.gi_code.co_cellvars = ()

yes.gi_code.co_code = '|\x00\x00]\x0b\x00}\x01\x00|\x01\x00V\x01q\x03\x00d\x00\x00S'

yes.gi_code.co_consts = (None,)

yes.gi_code.co_filename = '<pyshell#46>'

yes.gi_code.co_firstlineno = 1

yes.gi_code.co_flags = 99

yes.gi_code.co_freevars = ()

yes.gi_code.co_lnotab = '\x06\x00'

yes.gi_code.co_name = '<genexpr>'

yes.gi_code.co_names = ()

yes.gi_code.co_nlocals = 2

yes.gi_code.co_stacksize = 2

yes.gi_code.co_varnames = ('.0', 'x')

>>>

【1】function没有*args或**kw时,func.func_code.co_flags=67;

【2】function有*args没有**kw时,func.func_code.co_flags=71;

【3】function没有*args有**kw时,func.func_code.co_flags=75;

【4】function既有*args也有**kw时,func.func_code.co_flags=79;

【5】function是一个generator时,func.gi_code.co_flags=99.

3.获取func函数的所有位置参数的个数:

func.func_code.co_argcount

4.获取func函数签名:

[1]callable(func),True=>function,False=>generator

[2]func的定义的所有位置参数变量名:pVars=func.func_code.co_varnames[:func.func_code.co_argcount]

[3]func的默认参数及默认值:func.func_defaults

[4]func的所有带默认值的参数的参数名:dVars=pVars[-len(func.func_defaults):]【当然首先要判断func.func_defaults=?=None】

[5]根据func.func_code.co_flags来判断有无带星号的参数,按照上面的判定规则:

a.如果func.func_code.co_flags==67,无带星号的参数;

b.如果func.func_code.co_flags==71,只有带一个星号的参数,它的参数名是func.func_code.co_varnames[func.func_code.co_argcount]

c.如果func.func_code.co_flags==75,只有带两个星号的参数,它的参数名是func.func_code.co_varnames[func.func_code.co_argcount]

d. 如果func.func_code.co_flags==79,有两个带星号的参数,它们的参数名是 func.func_code.co_varnames[func.func_code.co_argcount:func.func_code.co_argcount+2], 其中第一个是带一个星号的,第二个是带两个星号的

因为:

1 >>>def yes(**kw,*args):pass2SyntaxError: invalid syntax3 >>>

故如此。到此,func函数的函数签名就可以被还原了。

二、func.func_*

1.func.func_closure:

2.func.func_code:详见下面第三条

3.func.func_defaults:tuple=>func函数的参数中的所有默认值

4.func.func_dict

5.func.func_doc:str=>func函数的文档字符串

6.func.func_globals:dict=>func函数的全局环境

7.func.func_name:str=>func函数的函数名

三、func.func_code【翻译有不周之处请指正】

1.func.func_code.co_argcount:co_argcountis the number of positional arguments (including arguments with default values);

int=>func函数的位置参数的个数,实际上python函数定义时定义的前面不加星号的所有参数都是位置参数,我们所说的关键字参数只是调用时候的说法。

2.func.func_code.co_cellvars:co_cellvarsis a tuple containing the names of local variables that are referenced by nested functions;

tuple=>func函数中所有被其嵌套函数引用了的func函数的局部变量

3.func.func_code.co_code:co_codeis a string representing the sequence of bytecode instructions;

str=>func函数的编译后的字节码

4.func.func_code.co_consts:co_constsis a tuple containing the literals used by the bytecode;

tuple=>func函数中的所有常量,如0,True,'',None

5.func.func_code.co_filename:co_filenameis the filename from which the code was compiled;

str=>func函数的定义所在的源文件路径

6.func.func_code.co_firstlineno:co_firstlinenois the first line number of the function;

int=>func函数的定义在其源文件中的第一行的行号

7.func.func_code.co_flags:co_flagsis an integer encoding a number of flags for the interpreter;

int=>func函数参数传递方式的编码,比如*args,**kw等形式

8.func.func_code.co_freevars:co_freevarsis a tuple containing the names of free variables;

tuple=>func函数中所有的自由变量的名称

9.func.func_code.co_lnotab:co_lnotabis a string encoding the mapping from bytecode offsets to line numbers (for details see the source code of the interpreter);

10.func.func_code.co_name:co_namegives the function name;

str=>func函数的名称

11.func.func_code.co_names:co_namesis a tuple containing the names used by the bytecode;

tuple=>func函数中所有的被字节码使用到的名称,比如模块名,方法名等

12.func.func_code.co_nlocals:co_nlocalsis the number of local variables used by the function (including arguments);

int=>func函数用到的局部变量的数目(包括参数)

13.func.func_code.co_stacksize:co_stacksizeis the required stack size (including local variables);

func函数所需的堆栈大小(包括所有局部变量)

14.func.func_code.co_varnames:co_varnamesis a tuple containing the names of the local variables (starting with the argument names);

tuple=>func函数中所有使用到的local variables的名称,参数按顺序排在最前面,其它的按在代码中出现的顺序排列;

四、看下面的一个实验:

1#coding=utf-82importos,sys34defdecorator(printResult=False):5def_decorator(func):6name=func.func_name7print'%s() was post to _decorator()'%name8def__decorator(*args,**kw):9print'Call the function %s() in __decorator().'%\10func.func_name11ifprintResult:12printfunc(*args,**kw),'#print in __decorator().'13else:14returnfunc(*args,**kw)15return__decorator16return_decorator1718defGetRandName(length,isVar=False):19u'''Get random name with string.letters+'_'+string.digits2021length=>The length of name.22isVar=>The name must be a varname.23'''24varName,chars=[],string.letters+'_'+string.digits25ifisVar:26varName.append(chars[:53][random.randint(0,52)])27length-=128foriinrange(length):29varName.append(chars[random.randint(0,62)])30varName=''.join(varName)31returnvarName3233deffunc_info(func):34print'%s() information:'%func.func_name35fornamein[xforxindir(func)ifx.startswith('func_')]:36print'%s.%s = %r'%(func.func_name,name,37eval('%s.%s'%(func.func_name,name)))38fornamein[xforxindir(func.func_code)ifx.startswith('co_')]:39print'%s.func_code.%s = %r'%(func.func_name,name,40eval('%s.func_code.%s'%(func.func_name,name)))41#输出GetRandName()函数的信息42func_info(GetRandName)43print'-'*8044#输出decorator()函数的信息45func_info(decorator)46print'-'*8047#将GetRandName函数用装饰器先装饰一下48GetRandName=decorator(True)(GetRandName)49#装饰后GetRandName变成__decorator()函数50print'GetRandName=%r'%GetRandName51#输出此时的GetRandName即__decorator()函数的信息52print'%s() information:'%GetRandName.func_name53fornamein[xforxindir(GetRandName)ifx.startswith('func_')]:54print'%s.%s = %r'%(GetRandName.func_name,name,55eval('GetRandName.%s'%name))56fornamein[xforxindir(GetRandName.func_code)ifx.startswith('co_')]:57print'%s.func_code.%s = %r'%(GetRandName.func_name,name,58eval('GetRandName.func_code.%s'%name))

运行结果:

1Python 2.7.8 (default, Jun 30 2014, 16:08:48) [MSC v.1500 64bit (AMD64)] on win322Type"copyright","credits"or"license()"formore information.3>>> ================================ RESTART ================================4>>>5GetRandName() information:6GetRandName.func_closure =None7GetRandName.func_code = <code object GetRandName at 0000000002107F30, file"E:\文档\程序库\Python程序\func_information.py", line 18>8GetRandName.func_defaults =(False,)9GetRandName.func_dict ={}10GetRandName.func_doc = u"Get random name with string.letters+'_'+string.digits\n\n length=>The length of name.\n isVar=>The name must be a varname.\n"11GetRandName.func_globals = {'__builtins__': <module'__builtin__'(built-in)>,'__file__':'E:\\\xce\xc4\xb5\xb5\\\xb3\xcc\xd0\xf2\xbf\xe2\\Python\xb3\xcc\xd0\xf2\\func_information.py','func_info': <function func_info at 0x0000000002BDD3C8>,'__package__': None,'sys': <module'sys'(built-in)>,'__name__':'__main__','GetRandName': <function GetRandName at 0x0000000002BE0D68>,'os': <module'os'from'D:\Python27\lib\os.pyc'>,'__doc__': None,'decorator': <function decorator at 0x00000000021199E8>}12GetRandName.func_name ='GetRandName'13GetRandName.func_code.co_argcount = 214GetRandName.func_code.co_cellvars =()15GetRandName.func_code.co_code ='g\x00\x00t\x00\x00j\x01\x00d\x01\x00\x17t\x00\x00j\x02\x00\x17\x02}\x02\x00}\x03\x00|\x01\x00rO\x00|\x02\x00j\x03\x00|\x03\x00d\x02\x00 t\x04\x00j\x05\x00d\x03\x00d\x04\x00\x83\x02\x00\x19\x83\x01\x00\x01|\x00\x00d\x05\x008}\x00\x00n\x00\x00x1\x00t\x06\x00|\x00\x00\x83\x01\x00D]#\x00}\x04\x00|\x02\x00j\x03\x00|\x03\x00t\x04\x00j\x05\x00d\x03\x00d\x06\x00\x83\x02\x00\x19\x83\x01\x00\x01q\\\x00Wd\x07\x00j\x07\x00|\x02\x00\x83\x01\x00}\x02\x00|\x02\x00S'16GetRandName.func_code.co_consts = (u"Get random name with string.letters+'_'+string.digits\n\n length=>The length of name.\n isVar=>The name must be a varname.\n",'_', 53, 0, 52, 1, 62,'')17GetRandName.func_code.co_filename ='E:\\\xce\xc4\xb5\xb5\\\xb3\xcc\xd0\xf2\xbf\xe2\\Python\xb3\xcc\xd0\xf2\\func_information.py'18GetRandName.func_code.co_firstlineno = 1819GetRandName.func_code.co_flags = 6720GetRandName.func_code.co_freevars =()21GetRandName.func_code.co_lnotab ='\x00\x06\x1b\x01\x06\x01!\x01\r\x01\x13\x01!\x01\x0f\x01'22GetRandName.func_code.co_name ='GetRandName'23GetRandName.func_code.co_names = ('string','letters','digits','append','random','randint','range','join')24GetRandName.func_code.co_nlocals = 525GetRandName.func_code.co_stacksize = 626GetRandName.func_code.co_varnames = ('length','isVar','varName','chars','i')27--------------------------------------------------------------------------------28decorator() information:29decorator.func_closure =None30decorator.func_code = <code object decorator at 0000000002107AB0, file"E:\文档\程序库\Python程序\func_information.py", line 4>31decorator.func_defaults =(False,)32decorator.func_dict ={}33decorator.func_doc =None34decorator.func_globals = {'__builtins__': <module'__builtin__'(built-in)>,'__file__':'E:\\\xce\xc4\xb5\xb5\\\xb3\xcc\xd0\xf2\xbf\xe2\\Python\xb3\xcc\xd0\xf2\\func_information.py','func_info': <function func_info at 0x0000000002BDD3C8>,'__package__': None,'sys': <module'sys'(built-in)>,'__name__':'__main__','GetRandName': <function GetRandName at 0x0000000002BE0D68>,'os': <module'os'from'D:\Python27\lib\os.pyc'>,'__doc__': None,'decorator': <function decorator at 0x00000000021199E8>}35decorator.func_name ='decorator'36decorator.func_code.co_argcount = 137decorator.func_code.co_cellvars = ('printResult',)38decorator.func_code.co_code ='\x87\x00\x00f\x01\x00d\x01\x00\x86\x00\x00}\x01\x00|\x01\x00S'39decorator.func_code.co_consts = (None, <code object _decorator at 0000000002107830, file"E:\文档\程序库\Python程序\func_information.py", line 5>)40decorator.func_code.co_filename ='E:\\\xce\xc4\xb5\xb5\\\xb3\xcc\xd0\xf2\xbf\xe2\\Python\xb3\xcc\xd0\xf2\\func_information.py'41decorator.func_code.co_firstlineno = 442decorator.func_code.co_flags = 343decorator.func_code.co_freevars =()44decorator.func_code.co_lnotab ='\x00\x01\x0f\x0b'45decorator.func_code.co_name ='decorator'46decorator.func_code.co_names =()47decorator.func_code.co_nlocals = 248decorator.func_code.co_stacksize = 249decorator.func_code.co_varnames = ('printResult','_decorator')50--------------------------------------------------------------------------------51GetRandName() was post to _decorator()52GetRandName=<function__decoratorat 0x0000000002BDD4A8>53__decorator() information:54__decorator.func_closure = (<cell at 0x0000000002BF18E8: function object at 0x0000000002BE0D68>, <cell at 0x0000000002BF1828: bool object at 0x000000001E284280>)55__decorator.func_code = <code object__decoratorat 0000000002124030, file"E:\文档\程序库\Python程序\func_information.py", line 8>56__decorator.func_defaults =None57__decorator.func_dict ={}58__decorator.func_doc =None59__decorator.func_globals = {'name':'func_globals','__builtins__': <module'__builtin__'(built-in)>,'__file__':'E:\\\xce\xc4\xb5\xb5\\\xb3\xcc\xd0\xf2\xbf\xe2\\Python\xb3\xcc\xd0\xf2\\func_information.py','func_info': <function func_info at 0x0000000002BDD3C8>,'__package__': None,'sys': <module'sys'(built-in)>,'x':'func_name','__name__':'__main__','GetRandName': <function__decoratorat 0x0000000002BDD4A8>,'os': <module'os'from'D:\Python27\lib\os.pyc'>,'__doc__': None,'decorator': <function decorator at 0x00000000021199E8>}60__decorator.func_name ='__decorator'61__decorator.func_code.co_argcount =062__decorator.func_code.co_cellvars =()63__decorator.func_code.co_code ="d\x01\x00\x88\x00\x00j\x00\x00\x16GH\x88\x01\x00r'\x00\x88\x00\x00|\x00\x00|\x01\x00\x8e\x00\x00Gd\x02\x00GHn\r\x00\x88\x00\x00|\x00\x00|\x01\x00\x8e\x00\x00Sd\x00\x00S"64__decorator.func_code.co_consts = (None,'Call the function %s() in __decorator().','#print in __decorator().')65__decorator.func_code.co_filename ='E:\\\xce\xc4\xb5\xb5\\\xb3\xcc\xd0\xf2\xbf\xe2\\Python\xb3\xcc\xd0\xf2\\func_information.py'66__decorator.func_code.co_firstlineno = 867__decorator.func_code.co_flags = 3168__decorator.func_code.co_freevars = ('func','printResult')69__decorator.func_code.co_lnotab ='\x00\x01\x03\x01\t\x01\x06\x01\x15\x02'70__decorator.func_code.co_name ='__decorator'71__decorator.func_code.co_names = ('func_name',)72__decorator.func_code.co_nlocals = 273__decorator.func_code.co_stacksize = 374__decorator.func_code.co_varnames = ('args','kw')75>>>

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航