python ix函数_Python函数信息

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

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

1.获取原函数名称:

1 >>> def yes():pass

2

3 >>> a=yes

4 >>>a.func_name

5 'yes'

6 >>>

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

[python docs]:The following flag bits are defined for co_flags: bit 0x04 is set if the function uses the *arguments syntax to accept an arbitrary number of positional arguments; bit 0x08 is set if the function uses the **keywords syntax to accept arbitrary keyword arguments; bit 0x20 is 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=(x for x in range(100))

>>>yes

at 0x0000000002FF22D0>

>>> [x for x in dir(yes) if not 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 = ''

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 = ''

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):pass

2 SyntaxError: invalid syntax

3 >>>

故如此。到此,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_argcount is the number of positional arguments (including arguments with default values);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

9.func.func_code.co_lnotab:co_lnotab is 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_name gives the function name;

str=>func函数的名称

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

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

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

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

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

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

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

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

四、看下面的一个实验:

1 #coding=utf-8

2 importos,sys3

4 def decorator(printResult=False):5 def_decorator(func):6 name=func.func_name7 print '%s() was post to _decorator()'%name8 def __decorator(*args,**kw):9 print 'Call the function %s() in __decorator().'%\10 func.func_name11 ifprintResult:12 print func(*args,**kw),'#print in __decorator().'

13 else:14 return func(*args,**kw)15 return __decorator

16 return_decorator17

18 def GetRandName(length,isVar=False):19 u'''Get random name with string.letters+'_'+string.digits20

21 length=>The length of name.22 isVar=>The name must be a varname.23 '''

24 varName,chars=[],string.letters+'_'+string.digits25 ifisVar:26 varName.append(chars[:53][random.randint(0,52)])27 length-=1

28 for i inrange(length):29 varName.append(chars[random.randint(0,62)])30 varName=''.join(varName)31 returnvarName32

33 deffunc_info(func):34 print '%s() information:'%func.func_name35 for name in [x for x in dir(func) if x.startswith('func_')]:36 print '%s.%s = %r'%(func.func_name,name,37 eval('%s.%s'%(func.func_name,name)))38 for name in [x for x in dir(func.func_code) if x.startswith('co_')]:39 print '%s.func_code.%s = %r'%(func.func_name,name,40 eval('%s.func_code.%s'%(func.func_name,name)))41 #输出GetRandName()函数的信息

42 func_info(GetRandName)43 print '-'*80

44 #输出decorator()函数的信息

45 func_info(decorator)46 print '-'*80

47 #将GetRandName函数用装饰器先装饰一下

48 GetRandName=decorator(True)(GetRandName)49 #装饰后GetRandName变成__decorator()函数

50 print 'GetRandName=%r'%GetRandName51 #输出此时的GetRandName即__decorator()函数的信息

52 print '%s() information:'%GetRandName.func_name53 for name in [x for x in dir(GetRandName) if x.startswith('func_')]:54 print '%s.%s = %r'%(GetRandName.func_name,name,55 eval('GetRandName.%s'%name))56 for name in [x for x in dir(GetRandName.func_code) if x.startswith('co_')]:57 print '%s.func_code.%s = %r'%(GetRandName.func_name,name,58 eval('GetRandName.func_code.%s'%name))

运行结果:

1 Python 2.7.8 (default, Jun 30 2014, 16:08:48) [MSC v.1500 64bit (AMD64)] on win322 Type "copyright", "credits" or "license()" formore information.3 >>> ================================ RESTART ================================

4 >>>

5 GetRandName() information:6 GetRandName.func_closure =None7 GetRandName.func_code =

8 GetRandName.func_defaults =(False,)9 GetRandName.func_dict ={}10 GetRandName.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"

11 GetRandName.func_globals = {'__builtins__': , '__file__': 'E:\\\xce\xc4\xb5\xb5\\\xb3\xcc\xd0\xf2\xbf\xe2\\Python\xb3\xcc\xd0\xf2\\func_information.py', 'func_info': , '__package__': None, 'sys': , '__name__': '__main__', 'GetRandName': , 'os': , '__doc__': None, 'decorator': }12 GetRandName.func_name = 'GetRandName'

13 GetRandName.func_code.co_argcount = 2

14 GetRandName.func_code.co_cellvars =()15 GetRandName.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'

16 GetRandName.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, '')17 GetRandName.func_code.co_filename = 'E:\\\xce\xc4\xb5\xb5\\\xb3\xcc\xd0\xf2\xbf\xe2\\Python\xb3\xcc\xd0\xf2\\func_information.py'

18 GetRandName.func_code.co_firstlineno = 18

19 GetRandName.func_code.co_flags = 67

20 GetRandName.func_code.co_freevars =()21 GetRandName.func_code.co_lnotab = '\x00\x06\x1b\x01\x06\x01!\x01\r\x01\x13\x01!\x01\x0f\x01'

22 GetRandName.func_code.co_name = 'GetRandName'

23 GetRandName.func_code.co_names = ('string', 'letters', 'digits', 'append', 'random', 'randint', 'range', 'join')24 GetRandName.func_code.co_nlocals = 5

25 GetRandName.func_code.co_stacksize = 6

26 GetRandName.func_code.co_varnames = ('length', 'isVar', 'varName', 'chars', 'i')27 --------------------------------------------------------------------------------

28 decorator() information:29 decorator.func_closure =None30 decorator.func_code =

31 decorator.func_defaults =(False,)32 decorator.func_dict ={}33 decorator.func_doc =None34 decorator.func_globals = {'__builtins__': , '__file__': 'E:\\\xce\xc4\xb5\xb5\\\xb3\xcc\xd0\xf2\xbf\xe2\\Python\xb3\xcc\xd0\xf2\\func_information.py', 'func_info': , '__package__': None, 'sys': , '__name__': '__main__', 'GetRandName': , 'os': , '__doc__': None, 'decorator': }35 decorator.func_name = 'decorator'

36 decorator.func_code.co_argcount = 1

37 decorator.func_code.co_cellvars = ('printResult',)38 decorator.func_code.co_code = '\x87\x00\x00f\x01\x00d\x01\x00\x86\x00\x00}\x01\x00|\x01\x00S'

39 decorator.func_code.co_consts = (None, )40 decorator.func_code.co_filename = 'E:\\\xce\xc4\xb5\xb5\\\xb3\xcc\xd0\xf2\xbf\xe2\\Python\xb3\xcc\xd0\xf2\\func_information.py'

41 decorator.func_code.co_firstlineno = 4

42 decorator.func_code.co_flags = 3

43 decorator.func_code.co_freevars =()44 decorator.func_code.co_lnotab = '\x00\x01\x0f\x0b'

45 decorator.func_code.co_name = 'decorator'

46 decorator.func_code.co_names =()47 decorator.func_code.co_nlocals = 2

48 decorator.func_code.co_stacksize = 2

49 decorator.func_code.co_varnames = ('printResult', '_decorator')50 --------------------------------------------------------------------------------

51 GetRandName() was post to _decorator()52 GetRandName=

53 __decorator() information:54 __decorator.func_closure = (, )55 __decorator.func_code =

56 __decorator.func_defaults =None57 __decorator.func_dict ={}58 __decorator.func_doc =None59 __decorator.func_globals = {'name': 'func_globals', '__builtins__': , '__file__': 'E:\\\xce\xc4\xb5\xb5\\\xb3\xcc\xd0\xf2\xbf\xe2\\Python\xb3\xcc\xd0\xf2\\func_information.py', 'func_info': , '__package__': None, 'sys': , 'x': 'func_name', '__name__': '__main__', 'GetRandName': , 'os': , '__doc__': None, 'decorator': }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 = 8

67 __decorator.func_code.co_flags = 31

68 __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 = 2

73 __decorator.func_code.co_stacksize = 3

74 __decorator.func_code.co_varnames = ('args', 'kw')75 >>>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值