我需要从 C++ 评估 Python 表达式。这段代码似乎有效:
PyObject * dict = PyDict_New();
PyObject * val = PyRun_String(expression, Py_eval_input, dict, 0);
Py_DECREF(dict);
Run Code Online (Sandbox Code Playgroud)
不幸的是,如果表达式是“假”的“真”(即 val 为 0 并且 PyErr_Occurred() 返回真),它会失败。我究竟做错了什么?他们不应该分别评估 Py_True 和 Py_False 吗?
这个问题与我之前提出的一个问题有关。即这一项,如果有人有兴趣。基本上,我想要做的是使用Py_buffer包装在memoryview-object 中的 C 数组向 Python 公开。我已经使用PyBuffer_FillInfo(工作 = 我可以在 Python 中操作数据并将其写入 C 中的标准输出),但是如果我尝试滚动我自己的缓冲区,我会在 C 函数返回后得到一个段错误。
我需要创建自己的缓冲区,因为 PyBuffer_FillInfo 假定格式为 char,使 itemsize 字段为 1。我需要能够提供大小为 1、2、4 和 8 的项目。
一些代码,这是一个工作示例:
Py_buffer *buf = (Py_buffer *) malloc(sizeof(*buf));
int r = PyBuffer_FillInfo(buf, NULL, malloc(sizeof(char) * 4), 4, 0, PyBUF_CONTIG);
PyObject *mv = PyMemoryView_FromBuffer(buf);
//Pack the memoryview object into an argument list and call the Python function
for (blah)
printf("%c\n", *buf->buf++); //this prints the values i set …Run Code Online (Sandbox Code Playgroud) 我是 cython 的新手,我只是在寻找一种将 numpy 数组转换为元组的简单方法,然后可以将其添加到和/或在字典中查找。
在 CPython 中,我可以使用 PyTuple_New 并迭代数组的值(将每个值添加到元组中,就像我将它们附加到列表一样)。
Cython 似乎没有提供通常的 CPython 函数。我怎么能打开一个数组:
array([1,2,3])
Run Code Online (Sandbox Code Playgroud)
成一个元组:
(1, 2, 3)
Run Code Online (Sandbox Code Playgroud) 在可视化调试器中调试 python 扩展时,检查器中 python 对象的原始解释对用户不友好。人们几乎看不到对象中的真实内容。有没有办法观察对象的python表示,比如vector<string>C++中的,它肯定是由visual studio转换为提供真实内容而不是低级实现的。
ps:以下是dict在python中的检查。

cpython python-c-api visual-studio python-c-extension python-2.7
作为处理将包含数千万或数亿个键的 dict 的优化,我真的非常想预先调整其容量……但似乎没有 Pythonic 方法可以这样做。
使用 Cython 或 C 标注直接调用 CPython 的内部函数(例如dictresize()或_PyDict__NewPresized() )来实现这一点是否可行?
我制作了一个 Python 模块 ( swood),直到最近,它还是一个包含许多类的大文件。将相关类重构为单独的文件后,一切仍然有效,尽管慢了大约 50%。我认为,如果有的话,它会变得更快一点,因为 Python 可以更有效地缓存每个文件的字节码,从而缩短启动时间。
我正在使用 CPython 运行此代码(尚未使用 PyPy 及其同类产品进行测试)。我已经line_profiler在旧版本和重构版本上运行,并且在重构前后每行花费的处理时间百分比看起来大致相同。
以下是关于我的程序的一些可能与它有关的事情:
Note并且实例化这些类可能很昂贵,尽管在重构之前这不是问题。import位于开头。numpy耗时最长的部分(缩放和混合音频)中发生了很多基于数组的操作是什么导致我的代码除了将其分成多个文件之外什么都不做而变得更慢?
我有一个从我的多线程 Python 应用程序调用的 C 扩展。我i在 C 函数的某处使用了一个静态变量,i++稍后我有一些语句可以从不同的 Python 线程运行(尽管该变量仅在我的 C 代码中使用,但我不会将其交给 Python)。
出于某种原因,到目前为止我还没有遇到任何比赛条件,但我想知道这是否只是运气......
我没有任何与线程相关的 C 代码(没有 Py_BEGIN_ALLOW_THREADS 或任何东西)。
我知道 GIL 只保证单个字节码指令是原子和线程安全的,因此i+=1Python 中的语句不是线程安全的。
但我不知道i++C 扩展中的指令。有什么帮助吗?
假设我有一个数组
from array import array
myarr = array('l', [1, 2, 3])
Run Code Online (Sandbox Code Playgroud)
和一个变量:
myvar = 4
创建新数组的最快方法是什么:
newarray = array('l', [1, 2, 3, 4])
Run Code Online (Sandbox Code Playgroud)
您可以假设所有元素都是“长”类型
我试图创建一个新数组array.append()
并不确定它是否最快。我正在考虑使用memoryviewlike:
malloc(4*sizeof(long))
但我不知道如何将较短的数组复制到 memoryview 的一部分中。然后将最后一个元素插入最后一个位置。
我对 Cython 相当陌生。谢谢你的帮助!
更新:我比较了以下三种方法:
Cython: [100000 个循环,最好的 3 个:每个循环 5.94 µs]
from libc.stdlib cimport malloc
def cappend(long[:] arr, long var, size_t N):
cdef long[:] result = <long[:(N+1)]>malloc((N+1)*sizeof(long))
result.base[:N] = arr
result.base[N] = var
return result
Run Code Online (Sandbox Code Playgroud)
数组: [1000000 个循环,最好的 3 个:每个循环 1.21 µs]
from array import array
import …Run Code Online (Sandbox Code Playgroud) 我在 Python 3.6 中看到了我不期望的行为,这与reload在 Python 2.7(和 3.4)中使用普通的行为不同。也就是说,似乎在模块初始化期间或在重新加载期间重新执行模块时填充的模块属性在其本地名称被删除后不会恢复del......见下文:
对于 Python 3.6:
In [1]: import importlib
In [2]: import math
In [3]: del math.cos
In [4]: math.cos
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-4-05b06e378197> in <module>()
----> 1 math.cos
AttributeError: module 'math' has no attribute 'cos'
In [5]: math = importlib.reload(math)
In [6]: math.cos
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-6-05b06e378197> in <module>()
----> 1 math.cos
AttributeError: module 'math' has no …Run Code Online (Sandbox Code Playgroud) 我正在开发一个 C 扩展,现在我想追踪内存泄漏。通过阅读 Python 的文档,很难理解何时增加/减少 Python 对象的引用计数。此外,在花了几天时间尝试嵌入 Python 解释器(为了将扩展编译为独立程序)之后,我不得不放弃这项努力。所以,像 Valgrind 这样的工具在这里是无能为力的。
到目前为止,通过反复试验,我了解到,例如,这Py_DECREF(Py_None)是一件坏事……但这是否适用于任何常数?我不知道。
到目前为止,我的主要困惑可以这样列出:
PyWhatever_New()如果它不超过创建它的程序,我是否必须减少它创建的任何东西的refcount?Py_INCREF需要与 匹配Py_DECREF,还是应该有一个/另一个?PyObject*,我是否需要增加它以确保我仍然可以使用它(永远),或者减少它以确保最终它会被垃圾收集,或者两者都不需要?Py_INCREF在堆上重新分配它们)。cpython ×10
python ×8
arrays ×2
cython ×2
numpy ×2
python-2.7 ×2
python-c-api ×2
boolean ×1
c ×1
dictionary ×1
pep3118 ×1
performance ×1
pybuffer ×1
python-3.5 ×1
python-3.x ×1