Python内核之PyCodeObject

 



在Python内核看来,任何一个代码作用域都会对应一个PyCodeObject。

Py3K的PyCodeObject定义在code.h中,位于/branches/py3k/Include,如下所示


/* Bytecode object */

typedef struct {

    PyObject_HEAD

    int co_argcount; /* #arguments, except *args */

    int co_kwonlyargcount; /* #keyword only arguments */

    int co_nlocals; /* #local variables */

    int co_stacksize; /* #entries needed for evaluation stack */

    int co_flags; /* CO_..., see below */

    PyObject *co_code; /* instruction opcodes */

    PyObject *co_consts; /* list (constants used) */

    PyObject *co_names; /* list of strings (names used) */

    PyObject *co_varnames; /* tuple of strings (local variable names) */

    PyObject *co_freevars; /* tuple of strings (free variable names) */

    PyObject *co_cellvars;      /* tuple of strings (cell variable names) */

    /* The rest doesn't count for hash or comparisons */

    PyObject *co_filename; /* unicode (where it was loaded from) */

    PyObject *co_name; /* unicode (name, for reference) */

    int co_firstlineno; /* first source line number */

    PyObject *co_lnotab; /* string (encoding addr<->lineno mapping) */

    void *co_zombieframe;     /* for optimization only (see frameobject.c) */

} PyCodeObject;



1. argcount vs. kwonlyargcount

[http://www.python.org/dev/peps/pep-3102]


argcount

在调用时必须出现的参数的个数,不包含可变参数


kwonlyargcount

在调用时必须出现、形式为"key=value"、出现在可变参数之后的参数的个数


举例:

-------------------------------------------------------

def weirdo(a,b,*c,d):

pass

print(weirdo.__code__.co_argcount)

print(weirdo.__code__.co_kwonlyargcount)

-------------------------------------------------------

结果:

-------------------------------------------------------

2

1

-------------------------------------------------------


2. co_nlocals

所有参数的个数,包括argcount+kwonlyargcount,还有可变参数的个数


举例:

-------------------------------------------------------

>>> def weirdo(a,b,*c,d):pass

...

>>> weirdo.__code__.co_nlocals

4

-------------------------------------------------------


3. co_varnames vs. co_freevars vs. co_cellvars

co_varnames

在本代码段中被赋值、没有被内层代码段引用的变量


co_freevars

在本代码段中被引用、在外层代码被赋值的变量


co_cellvars

在本代码段中被赋值、且被内层代码段引用的变量


[记忆]

free自由,cell牢房

cell变量是被内层代码段约束的变量


举例:

-------------------------------------------------------

def fa():

a = 1

        b = 2

def fb():

c = a

                d = 3

print(fb.__code__.co_varnames)

print(fb.__code__.co_freevars)

print(fb.__code__.co_cellvars)

fa()

print(fa.__code__.co_varnames)

print(fa.__code__.co_freevars)

print(fa.__code__.co_cellvars)

-------------------------------------------------------

结果:

-------------------------------------------------------

('c','d')

('a',)

()

('b','fb')

()

('a',)

-------------------------------------------------------


4. co_filename vs. co_name

前者代表代码段所在文件的全名对应的对象,后者代表本代码段的名字对应的对象。


如果是在Python Shell中定义的代码段,因为代码段是用户用键盘一字一字敲入,所在文件的名字是<stdin>,


举例:

------------------------------------------------

>>> def fa():pass

...

>>> fa.__code__.co_filename

'<stdin>'

------------------------------------------------

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值