我想了解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 还必须做一些其他的解释工作。所以,我的问题是如何仅调试相关的操作码指令?
基本上,我如何知道我正在调试的指令实际上来自我创建的程序?
请帮我解决同样的问题。提前致谢。
我正在使用该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 脚本创建一个 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 库 …
所以我最近看到了对 Python 解释器和编译器(特别是 CPython)的解释。
如果我错了,请纠正我。我只是想确保我理解这些具体概念。
那么 CPython 既被编译(为字节码),又被解释(在 PVM 中)?PVM 到底是做什么的?它是否逐行读取字节码,并将每一行转换为可以在特定计算机上执行的二进制指令?这是否意味着基于 Intel 处理器的计算机需要与基于 AMD 的计算机不同的 PVM?
我正在做很多基准测试。我从来没有见过这样的事情。我很困惑。创建一个根本不使用的额外全局变量可以使我的部分代码速度提高约 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) 当我使用按位与运算符( &) 与数字 1 来确定数字 x 是奇数还是偶数时(x & 1),解释器是否会根据 x 的二进制表示形式更改 1 的二进制表示形式?例如:
它是否会在 1 的二进制表示后追加 0 来执行按位与运算?
查看cpython 实现,看起来它是根据正确参数的大小来比较数字的。所以在这种情况下,上面的例子实际上是有效的:
我正在为 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) 我正在尝试使用ctypes从内部python结构中提取数据.也就是说,我正在尝试读取xrange中的4个字段:
typedef struct {
PyObject_HEAD
long start;
long step;
long len;
} rangeobject;
Run Code Online (Sandbox Code Playgroud)
有没有标准的方法来获取python本身的这些领域?
我正在尝试实现我自己的方法缓存.为此,首先我要禁用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) 似乎有一些一致性,因为调用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])...
... 这里发生了什么?
cpython ×10
python ×9
amazon-ecr ×1
aws-lambda ×1
c ×1
c++ ×1
caching ×1
ctypes ×1
docker ×1
gdb ×1
methods ×1
performance ×1
xrange ×1