标签: cpython

如何在Python中获取mmap内存的地址?

我无法弄清楚如何获取 Python 中标准mmap对象的虚拟地址(来自 mmap 模块)。记录的方法似乎仅以字节数组或字符串的形式访问内存。

但我需要一次精确地访问 mmap'ped 内存 2 或 4 个字节 - 因为我的应用程序中的该内存被映射到硬件寄存器(想想 /dev/mem 或 GPIO 等)。使用ctypes模块可以以这种方式访问​​内存- 但为此我需要映射的指针- 或虚拟地址。

目前,我通过使用 libc 中的本机 open() 和 mmap() 函数(感谢相同的 ctypes)来克服这个问题,但我宁愿不这样做。

为什么 mmap 模块不提供简单的方法来获取内存地址?希望我错过了一些明显的东西......

-- DD

python cpython hardware-interface

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

Python:为什么partition(sep)比split(sep, maxsplit=1)更快

我发现了一个有趣的事情,它比在分隔符之后获取整个子字符串partition更快。split我已经在 Python 3.5 和 3.6 (Cpython) 中进行了测试

\n
In [1]: s = \'validate_field_name\'\n\nIn [2]: s.partition(\'_\')[-1]\nOut[2]: \'field_name\'\n\nIn [3]: s.split(\'_\', maxsplit=1)[-1]\nOut[3]: \'field_name\'\n\nIn [4]: %timeit s.partition(\'_\')[-1]\n220 ns \xc2\xb1 1.12 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000000 loops each)\n\nIn [5]: %timeit s.split(\'_\', maxsplit=1)[-1]\n745 ns \xc2\xb1 48.8 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000000 loops each)\n\nIn [6]: %timeit s[s.find(\'_\')+1:]\n340 ns \xc2\xb1 1.44 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000000 …
Run Code Online (Sandbox Code Playgroud)

python string algorithm performance cpython

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

可以为 PyLint 的不可检测模块创建“存根”文件吗?

我的 Python 项目是从 C++ 应用程序嵌入和解释的。此应用程序还将某些类/函数公开到 Python 可以导入的名为“Monsters”的模块中。因此,从中导入“史莱姆”类将如下所示:from Monsters import Slime

问题是 PyLint 由于其实现的性质而无法检测到此模块。因此,它会生成错误,例如:Unable to import 'Monsters'。这些类型的错误本身不是问题,因为它们可以被抑制而不会出现问题。

但是,该模块包含需要在 Python 中扩展的类。这些子类可以访问它们在 C++ 实现中构建的父变量/函数。访问它们会导致另一个错误:Instance of 'Child_Slime' has no 'x' member。“x”属性在父类中实现,但 PyLint 不知道它。

这种检查对象/类中的某些成员是否存在的能力是我想使用 PyLint 的一个重要原因,所以如果我不必完全抑制警告,我更愿意。有什么方法可以生成类似于 MyPy 的存根文件,但用于 PyLint?如果没有,是否有任何替代的 Python linter 包含这样的功能?

python cpython subclass pylint

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

Python C API 中的 PyCompilerFlags 是什么?

如果您查看了有关通过 C 调用运行 Python 代码的Python C-API文档,您总会发现提到PyCompilerFlags,但除了文档的最后一部分之外,没有任何内容真正描述它是什么,并且没有说明其可能的值及其对执行的影响。

python cpython

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

如何查明我正在使用哪个 CPython 版本?

我正在尝试从Unofficial Windows Binaries for Python Extension Packages安装 OpenCV 。

\n\n

我下载了以下文件:opencv_python\xe2\x80\x913.4.3\xe2\x80\x91cp37\xe2\x80\x91cp37m\xe2\x80\x91win_amd64.whl,\n当我这样做时pip install "opencv_python\xe2\x80\x913.4.3\xe2\x80\x91cp37\xe2\x80\x91cp37m\xe2\x80\x91win_amd64.whl",弹出了一条错误消息。

\n\n

错误opencv_python-3.4.3+contrib-cp37-cp37m-win_amd64.whl is not a supported wheel on this platform.

\n\n

根据我在谷歌搜索和 SO-ing 后了解到的情况,这是由于CPython构建之间不匹配(下载的 Wheel 文件和我系统上的 Python 环境之间)造成的问题。

\n\n

因此,我尝试寻找方法来确定我的系统上是哪个 CPython 版本,但失败了。

\n\n

到目前为止我尝试过的:

\n\n
import platform\nplatform.python.implementation()\n
Run Code Online (Sandbox Code Playgroud)\n\n

这给出了:

\n\n
\'CPython\' \n
Run Code Online (Sandbox Code Playgroud)\n\n

此外,我尝试了 \nplatform.architecture()\n 给出了:

\n\n
(\'64bit\', \'WindowsPE\')\n
Run Code Online (Sandbox Code Playgroud)\n\n

后来我只是搜索了我的site-packages文件夹并找到了一些文件,例如__init__.cpython-36.pyc因此假设我正在使用 CPython 3.6

\n\n

是否有更多基于编程的方法来通过终端检查相同的内容?

\n\n

任何形式的帮助表示赞赏。TIA。

\n

python windows cpython pip

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

正确替换函数的代码对象

我试图获取一个函数的源代码,向其中添加代码,然后将其放回原始函数中。

基本上是这样的:

new_code = change_code(original_code)
throwaway_module = ModuleType('m')
exec(new_code, throwaway_module.__dict__)
func.__code__ = getattr(throwaway_module, func.__name__).__code__
Run Code Online (Sandbox Code Playgroud)

new_code不包含任何不在原始函数中的名称时,这非常有效。

但是,当new_code包含原始中不存在的变量名称时,func在最后一行我收到以下错误:

ValueError: func() requires a code object with 1 free vars, not 0
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

编辑:

似乎我在 CPython 源代码中找到了引发此异常的位置(文件 funcobject.c)。为清楚起见省略了一些行:

static int
func_set_code(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored))
{
    Py_ssize_t nfree, nclosure;

    // ... lines omitted

    nfree = PyCode_GetNumFree((PyCodeObject *)value);
    nclosure = (op->func_closure == NULL ? 0 :
            PyTuple_GET_SIZE(op->func_closure));
    if (nclosure != nfree) {
        PyErr_Format(PyExc_ValueError,
                     "%U() requires a code object …
Run Code Online (Sandbox Code Playgroud)

python cpython metaprogramming

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

当 gc 处理引用循环时,python 如何停止世界?

python gc.collect()是一个停止世界(STW)垃圾收集器吗?

如果是 STW 垃圾收集器,何时何地停止世界?

我知道 python 使用确定性引用计数,这不需要停止世界。然而,在处理循环时,python 是否需要停止世界?

python cpython

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

在运行时动态设置Python解释器优化

经过一段时间在这里寻找重复项后,我发现唯一的事情是无操作并使用 Cython 进行优化,这是完全不相关的。我想要完成的是在运行时动态设置python -O标志。

基本上,有一个值sys.flags.optimize是只读的。我正在寻找一个选项来更改它或找到一个可以更改该值并影响字节码生成的位置。

根据文档,官方方法是在解释器启动之前调用它,所以我想知道这是否可能,但这就是我发现的:

这似乎py_compile被称为“某处”(GitHub 搜索仅显示文档或测试,而不是运行时的实际调用者)并optimization_levelcompiler.c上面管理。这意味着我可以在 Python 中更改它,并让编译的解释器在同一会话/进程中对经过或不经过优化的代码进行汇编。

我似乎找不到 CLI 参数解析,也找不到任何可以在运行时更改的相关“状态”。

我的目标(目前)是选择性地允许/删除assert关键字,该关键字可以单独完成-O(通过compiler_assert()需要级别集,但是我正在努力寻找构建 AST 的 C 代码和实际的 Python 代码之间的“缺失的链接”)似乎保持配置状态(因为py_compile包含原始optimize值)并且似乎正在为解释器本身编译和加载字节码。

有什么方法可以改变,optimization_level以便我可以实现这种行为,并且几乎可以在单个 Python 会话中完成此操作?

>>> # change optimize to 1
>>> def test(): assert True
>>> import dis
>>> dis.dis(test)
  1           0 LOAD_CONST               0 (None)
              2 …
Run Code Online (Sandbox Code Playgroud)

python interpreter assert cpython compiler-optimization

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

mylist.reverse() 和 list.reverse(mylist) 是如何执行的?

大概两者mylist.reverse()list.reverse(mylist)最终reverse_slicelistobject.cvialist_reverse_impl或 中执行PyList_Reverse。但他们实际上是如何到达那里的?从 Python 表达式到该 C 文件中的 C 代码的路径是什么?是什么将它们联系起来?它们经历了这两个反向函数中的哪一个(如果有的话)?

赏金更新:Dimitris 的回答(更新 2:我的意思是原始版本,现在扩展之前)及其下面的评论解释了部分内容,但我仍然缺少一些东西,希望看到一个全面的答案。

  • 来自两个 Python 表达式的两条路径如何收敛?如果我理解正确,反汇编和讨论字节码以及堆栈会发生什么,特别是LOAD_METHOD,将澄清这一点。(正如 Dimitris 回答下的评论所做的那样。)
  • 什么是压入堆栈的“未绑定方法”?它是“C 函数”(哪个?)还是“Python 对象”?
  • 我怎么知道它list_reverselistobject.c.h文件中的函数?我不认为 Python 解释器就像“让我们寻找一个听起来相似的文件和一个听起来相似的函数”。我宁愿怀疑该list类型是在某处定义的,并且以某种方式在名称“”下“注册” list,并且该reverse函数在名称“ reverse”下“注册”(也许这就是LIST_REVERSE_METHODDEF宏的作用?)。
  • 我对(对于这个问题)堆栈帧、参数处理和类似的东西不感兴趣(所以可能里面 发生的事情不多call_function)。真正让我感兴趣的是我最初所说的,从 Python 表达式到该 C 文件中的 C 代码的路径。最好是如何找到这样的路径。

解释我的动机:对于另一个问题,我想知道当我调用list.reverse(mylist). 我相当有信心通过浏览和搜索名称找到了它。但我想更加确定,并且更好地理解这些联系。

python cpython python-internals

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

为什么 [0] 是一个不同的函数而 0 不是?

我检查了.__code__对象的两个我认为不同但发现相同的函数,用于各种表达式。如果代码对象相同,据我所知,它们编译为相同的字节码,因此是“相同”的函数。

下表是之前插入的东西,; pass这使得g有不同的__code__。由于f是一个“什么都不做”的函数,这表明“相同”下的所有内容都不要执行,包括长算术。此外,元组是“相同的”,但列表和字符串是“差异”的——所以我们可能会得出结论,涉及不可变文字的未分配表达式不会被评估。但是,由于引发异常,这可能是“异常” - 那么vs.呢? 不会引发异常并且可以分配。1/010**9910**910**99

我无法从分析中看出太多;“相同”和“差异”都有无法区分的执行时间。然而,当它们可以被区分时,它总是带有“diff”。

如果“相同”从不执行,那么 Python 如何确定执行或不执行什么?如果它们确实执行,它们的代码对象如何相同?


相同

  • 0, (0,), True, False,None
  • 10 ** 9
  • ()
  • -314159.265358 ** (1/12345) / 2.718281828 + 500 - 7j

差异

  • [0], {0: 0}
  • 10 ** 99
  • [], {},""

比较代码

def compare(fn1, fn2):
    for name in dir(fn1.__code__):
        if (name.startswith("co_") …
Run Code Online (Sandbox Code Playgroud)

python cpython python-3.x

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