gpt4 book ai didi

python - CPython中函数对象和代码对象的关系

转载 作者:行者123 更新时间:2023-12-01 07:35:09 24 4
gpt4 key购买 nike

Include/funcobject.h CPython 源代码的以下注释开始:

Function objects and code objects should not be confused with each other:

Function objects are created by the execution of the 'def' statement. They reference a code object in their __code__ attribute, which is a purely syntactic object, i.e. nothing more than a compiled version of some source code lines. There is one code object per source code "fragment", but each code object can be referenced by zero or many function objects depending only on how many times the 'def' statement in the source was executed so far.

我不太明白。

<小时/>

这里写下我的部分理解。可能有人完成它。

  1. 编译阶段。

    我们有源文件Test.py:

    def a_func():
    pass

    解释器解析它并创建两个代码对象 - 一个用于Test.py,另一个用于a_funcTest.py 代码对象具有这样的 co_code 字段(反汇编):

      3           0 LOAD_CONST               0 (<code object a_func at 0x7f8975622b70, file "test.py", line 3>)
    2 LOAD_CONST 1 ('a_func')
    4 MAKE_FUNCTION 0
    6 STORE_NAME 0 (a_func)
    8 LOAD_CONST 2 (None)
    10 RETURN_VALUE

    此阶段没有创建函数对象。

  2. 执行阶段。

    • Function objects are created by the execution of the 'def' statement.

    当虚拟机到达MAKE_FUNCTION指令时,它会创建函数对象:

    typedef struct {
    PyObject_HEAD
    PyObject *func_code; /* A code object, the __code__ attribute */
    PyObject *func_globals; /* A dictionary (other mappings won't do) */
    PyObject *func_defaults; /* NULL or a tuple */
    PyObject *func_kwdefaults; /* NULL or a dict */
    PyObject *func_closure; /* NULL or a tuple of cell objects */
    PyObject *func_doc; /* The __doc__ attribute, can be anything */
    PyObject *func_name; /* The __name__ attribute, a string object */
    PyObject *func_dict; /* The __dict__ attribute, a dict or NULL */
    PyObject *func_weakreflist; /* List of weak references */
    PyObject *func_module; /* The __module__ attribute, can be anything */
    PyObject *func_annotations; /* Annotations, a dict or NULL */
    PyObject *func_qualname; /* The qualified name */
    } PyFunctionObject;
    • They reference a code object in their __code__ attribute, which is a purely syntactic object, i.e. nothing more than a compiled version of some source code lines.

    并将 a_func 代码对象放入 PyObject *func_code 字段中。现在,注释“函数对象和代码对象不相同”的信息已经很清楚了。

    • There is one code object per source code "fragment", but each code object can be referenced by zero or many function objects depending only on how many times the 'def' statement in the source was executed so far.

    不懂的部分用粗字体强调。

最佳答案

如果我创建一个 lambda 工厂(出于范围原因,这是一个好主意):

def mk_const(k):
def const(): return k
return const

然后有一个用于 mk_const 的代码对象和一个用于 const 的代码对象,但后者有许多函数对象作为对 mk_const 的调用(包括0)。

(使用lambda没有什么区别,但使用def更容易解释。)

它也可以是if的结果:

if lib.version>=4:
def f(x): return lib.pretty(x)
else:
def f(x): return str(x) # fallback

这里有两个代码对象(加上模块的一个),但最多使用其中一个。

关于python - CPython中函数对象和代码对象的关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57022457/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com