标签: cpython

如何在调试 cpython 时遍历 Python 操作码?

我想了解Python解释器的功能。我了解操作码的生成过程,并希望更好地理解解释器部分。为此,我在互联网上阅读了很多内容,并了解了python 解释器(Cpython)中的文件for (;;)循环ceval.c

现在我想解释以下Python代码a.py

a = 4
b = 5
c = a + b
Run Code Online (Sandbox Code Playgroud)

当我做python -m dis a.py

  1           0 LOAD_CONST               0 (4)
              2 STORE_NAME               0 (a)

  2           4 LOAD_CONST               1 (5)
              6 STORE_NAME               1 (b)

  3           8 LOAD_NAME                0 (a)
             10 LOAD_NAME                1 (b)
             12 BINARY_ADD
             14 STORE_NAME               2 (c)
             16 LOAD_CONST               2 (None)
             18 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)

现在我已将调试点switch(opcode)放入ceval.c. 现在,当我启动调试器时,它会出现这个位置 2000 多次。我认为这是因为在开始之前,Python 还必须做一些其他的解释工作。所以,我的问题是如何仅调试相关的操作码指令?

基本上,我如何知道我正在调试的指令实际上来自我创建的程序?

请帮我解决同样的问题。提前致谢。

c python gdb cpython

5
推荐指数
1
解决办法
823
查看次数

为什么函数中使用的对象属性被称为未绑定变量?

我正在使用该inspect模块来了解有关函数命名空间的更多信息:

import inspect

def foo():
    inspect.__cache__.update({'dummy': 0}) # Could be any class/attribute here

print(inspect.getclosurevars(foo))
Run Code Online (Sandbox Code Playgroud)

重新格式化输出:

ClosureVars(
    nonlocals={}, 
    globals={'inspect': <module 'inspect' from ='C:\\Users\\guido\\AppData\\Local\\Programs\\Python\\Python39\\lib\\inspect.py'>}, 
    builtins={}, 
    unbound={'__cache__', 'update'}
)
Run Code Online (Sandbox Code Playgroud)

为什么函数中使用的对象的属性(即__cache__update这种特殊情况下)被称为未绑定变量?


仔细观察inspect.getclosurevars可以确定字节码中的未绑定变量。更具体地说,它返回变量 in foo.__code__.co_namesthat is in foo.__globals__

所以真正的问题可能是:

  • 对象属性是否属于foo.__code__.co_names当前定义?这本身就是一个难题,因为它的定义似乎尚未确定
  • 模块像当前所做的那样inspect确定变量是否正确?unbound这里的正确是指返回值是否符合变量的定义unbound

python cpython

5
推荐指数
0
解决办法
100
查看次数

无法执行“gcc”:运行 docker build 时没有此类文件或目录

我试图为我的 python 脚本创建一个 docker 映像并将其上传到 AWS ECR,然后在 Lambda 中使用它。我们的Python运行时在AWS控制台上显示为3.8,所以我只是按照本手册操作: https ://docs.aws.amazon.com/lambda/latest/dg/images-create.html#images-create-from-base

但是当我运行 docker build -t image-name 时出现错误。

#6 14.02 gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/var/lang/include/python3.8 -c bitarray/_bitarray.c -o build/temp.linux-x86_64-3.8/bitarray/_bitarray.o
#6 14.02 unable to execute 'gcc': No such file or directory
#6 14.02 error: command 'gcc' failed with exit status 1
Run Code Online (Sandbox Code Playgroud)

我仔细检查了一下,我的 macOS 上安装了 gcc:

Warning: gcc 11.2.0 is already installed and up-to-date.
To reinstall 11.2.0, run:
brew reinstall gcc
Run Code Online (Sandbox Code Playgroud)

希望能提供一些解决此问题的帮助。谢谢!

编辑:此问题源于我在 Lambda 上运行脚本时无法导入 CPython 库 …

cpython amazon-web-services docker aws-lambda amazon-ecr

5
推荐指数
1
解决办法
7331
查看次数

CPython是如何实现的?

所以我最近看到了对 Python 解释器和编译器(特别是 CPython)的解释。

如果我错了,请纠正我。我只是想确保我理解这些具体概念。

那么 CPython 既被编译(为字节码),又被解释(在 PVM 中)?PVM 到底是做什么的?它是否逐行读取字节码,并将每一行转换为可以在特定计算机上执行的二进制指令?这是否意味着基于 Intel 处理器的计算机需要与基于 AMD 的计算机不同的 PVM?

python cpython

5
推荐指数
1
解决办法
612
查看次数

使用未使用的变量可以提高 20% 的速度?为什么?

我正在做很多基准测试。我从来没有见过这样的事情。我很困惑。创建一个根本不使用的额外全局变量可以使我的部分代码速度提高约 20%。为什么?

\n

我正在对一个生成可迭代对象的函数进行基准测试,测量消耗(迭代)它们所需的时间。我有两种食用方式。我获得高 CPU 份额的典型时间:

\n
       | Without the variable | With the variable \n-------+----------------------+-------------------\nOutput |   0.74 s  consume_1  |  0.72 s  consume_1 \n       |   0.96 s  consume_2  |  0.77 s  consume_2 \n       |                      |                    \n       |   0.74 s  consume_1  |  0.75 s  consume_1 \n       |   0.96 s  consume_2  |  0.78 s  consume_2 \n       |                      |                    \n       |   0.73 s  consume_1  |  0.73 s  consume_1 \n       |   0.95 s  consume_2  |  0.78 s  consume_2 \n-------+----------------------+-------------------\nDebug  |  Real time: …
Run Code Online (Sandbox Code Playgroud)

python performance cpython python-internals

5
推荐指数
0
解决办法
164
查看次数

按位“与”运算是否会在二进制表示形式前添加零?

当我使用按位与运算符( &) 与数字 1 来确定数字 x 是奇数还是偶数时(x & 1),解释器是否会根据 x 的二进制表示形式更改 1 的二进制表示形式?例如:

  • 2 & 1 -> 10 & 01 -> 然后按位比较
  • 5 & 1 -> 101 & 001 -> 然后按位比较
  • 100 & 1 -> 1100100 & 0000001 -> 然后按位比较

它是否会在 1 的二进制表示后追加 0 来执行按位与运算?

查看cpython 实现,看起来它是根据正确参数的大小来比较数字的。所以在这种情况下,上面的例子实际上是有效的:

  • 2 & 1 -> 10 & 1 -> 0 & 1 -> 然后按位比较
  • 5 & 1 -> 101 & 1 -> 1 & 1 -> 然后按位比较
  • 100 & …

python bit-manipulation cpython

5
推荐指数
1
解决办法
355
查看次数

如何使用可导入的子模块创建 python C++ 扩展

我正在为 python 创建一个 C++ 扩展。parent它创建一个包含子模块的模块child。有child一个方法hello()。如果我把它称为

import parent
parent.child.hello()
> 'Hi, World!'
Run Code Online (Sandbox Code Playgroud)

如果我尝试导入我的函数,它会失败

import parent
from parent.child import hello
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> ModuleNotFoundError: No module named 'parent.child'; 'parent' is not a package

parent.child
> <module 'child'>

Run Code Online (Sandbox Code Playgroud)

这是我的代码 setup.py

from setuptools import Extension, setup
  
# Define the extension module
extension_mod = Extension('parent',
                          sources=['custom.cc'])

# Define the setup parameters
setup(name='parent',
      version='1.0',
      description='A C++ extension …
Run Code Online (Sandbox Code Playgroud)

c++ python cpython python-extensions

5
推荐指数
1
解决办法
1026
查看次数

访问xrange内部结构

我正在尝试使用ctypes从内部python结构中提取数据.也就是说,我正在尝试读取xrange中的4个字段:

typedef struct {
    PyObject_HEAD
    long    start;
    long    step;
    long    len;
} rangeobject;
Run Code Online (Sandbox Code Playgroud)

有没有标准的方法来获取python本身的这些领域?

python ctypes cpython xrange

4
推荐指数
1
解决办法
352
查看次数

如何在CPython 2.7.2中停用方法缓存?

我正在尝试实现我自己的方法缓存.为此,首先我要禁用CPython 2.7.2中实现的现有方法缓存,因为我还想在没有此方法缓存的情况下对CPython进行基准测试.

我一直在查看代码并在'typeobject.c'文件中找到一些方法缓存代码:

/* Internal API to look for a name through the MRO.
   This returns a borrowed reference, and doesn't set an exception! */
PyObject *
_PyType_Lookup(PyTypeObject *type, PyObject *name)
{
    Py_ssize_t i, n;
    PyObject *mro, *res, *base, *dict;
    unsigned int h;

    if (MCACHE_CACHEABLE_NAME(name) &&
        PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) {
        /* fast path */
        h = MCACHE_HASH_METHOD(type, name);
        if (method_cache[h].version == type->tp_version_tag &&
            method_cache[h].name == name)
            return method_cache[h].value;
    }

    /* Look in tp_dict of types in MRO */
    mro = type->tp_mro; …
Run Code Online (Sandbox Code Playgroud)

python methods caching cpython

4
推荐指数
1
解决办法
185
查看次数

有没有人真正知道如何在Python中确定集合的顺序?

似乎有一些一致性,因为调用set()字符串似乎总是解析为相同的(非alabetical)顺序,并且两者都是

set([1,2,3]) & set([1,2,3,4])
Run Code Online (Sandbox Code Playgroud)

和它的表兄弟混在一起

set([2,3,1]) & set([4,3,1,2])
Run Code Online (Sandbox Code Playgroud)

将导致有序的set([1,2,3]).

另一方面,有点像racy,比如

from random import randint
set([randint(0,9) for x in range(3)])
Run Code Online (Sandbox Code Playgroud)

有时会给set([9, 6, 7])...

... 这里发生了什么?

python implementation cpython unordered-set

4
推荐指数
1
解决办法
98
查看次数