[更新:问题解决了!见帖子的底部]
我需要允许python开发人员将打包数据数组(在本例中为顶点)传递给我的API,这是一系列通过Python C API手动公开的C++接口.我对此的初步印象是使用ctypes Structure类来允许这样的接口:
class Vertex(Structure):
_fields_ = [
('x', c_float),
('y', c_float),
('z', c_float),
('u', c_float),
('v', c_float),
('color', c_int)
]
verts = (Vertex * 3)()
verts[0] = Vertex(0.0, 0.5, 0.0, 0.0, 0.5, 0xFF0000FF)
verts[1] = Vertex(0.5, -0.5, 0.0, 0.5, -0.5, 0x00FF00FF)
verts[2] = Vertex(-0.5, -0.5, 0.0, -0.5, -0.5, 0x0000FFFF)
device.ReadVertices(verts, 3) # This is the interfaces to the C++ object
Run Code Online (Sandbox Code Playgroud)
我试图传递的函数具有以下签名:
void Device::ReadVertices(Vertex* verts, int count);
Run Code Online (Sandbox Code Playgroud)
Python包装器看起来像这样:
static PyObject* Device_ReadVertices(Py_Device* self, PyObject* args)
{
PyObject* py_verts;
int …Run Code Online (Sandbox Code Playgroud) python文档说,cPickle比Pickle更快的原因是,前者是用C实现的.这究竟是什么意思?
我正在使用Python制作高级数学模块,有些计算需要花费大量时间.这是否意味着如果我的程序在C中实现,它可以更快?
我想从其他Python程序导入这个模块,就像我可以导入cPickle一样.
你能解释一下如何在C中实现Python模块吗?
要学习如何创建C扩展,我决定只复制一个内置.c文件(在本例中itertoolsmodule.c)并将其放在我的包中.我只能从更改的名称在模块内部itertools来mypkg.
然后我编译它(Windows 10,MSVC Community 14)setuptools.Extension:
from setuptools import setup, Extension
itertools_module = Extension('mypkg.itertoolscopy',
sources=['src/itertoolsmodulecopy.c'])
setup(...
ext_modules=[itertools_module])
Run Code Online (Sandbox Code Playgroud)
默认使用编译器标志/c /nologo /Ox /W3 /GL /DNDEBUG /MD,我在某处读取这些默认值等于python编译方式的设置.但是我使用conda(64位设置),所以这可能不一定是真的.
这一切都进展顺利 - 但是一个基准测试filterfalse显示它几乎比内置的慢2倍:
import mypkg
import itertools
import random
a = [random.random() for _ in range(500000)]
func = None
%timeit list(filter(func, a))
100 loops, best of 3: 3.42 ms per loop
%timeit list(itertools.filterfalse(func, a))
100 loops, best of 3: 3.41 ms …Run Code Online (Sandbox Code Playgroud) 我有一个C++函数返回一个std :: vector,我想在python中使用它,所以我使用的是C numpy api:
static PyObject *
py_integrate(PyObject *self, PyObject *args){
...
std::vector<double> integral;
cpp_function(integral); // This changes integral
npy_intp size = {integral.size()};
PyObject *out = PyArray_SimpleNewFromData(1, &size, NPY_DOUBLE, &(integral[0]));
return out;
}
Run Code Online (Sandbox Code Playgroud)
这是我从python中调用它的方式:
import matplotlib.pyplot as plt
a = py_integrate(parameters)
print a
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(a)
print a
Run Code Online (Sandbox Code Playgroud)
会发生什么:第一次打印没问题,值是正确的.但是当我描绘a他们不是; 在第二打印我看到这样很奇怪的值1E-308 1E-308 ...或0 0 0 ...为未初始化的内存.我不明白为什么第一次打印没问题.
static void DeleteVector(void *ptr)
{
std::cout << "Delete" << std::endl;
vector * v …Run Code Online (Sandbox Code Playgroud) __dict__在Python中定义一个"普通"类?__dict__s 的非动态类型的例子?PyTypeObject通过type_new?有一个tp_dict成员PyTypeObject,但我找不到有关它如何使用的信息.此外,还似乎有什么东西在事情typeobject.c的type_new,但我不能清楚地破译它.
以下是我发现的一些相关信息:
我有一个C文件,有一堆#defines用于我想从python引用的位.有足够的它们,我宁愿不将它们复制到我的python代码中,而是有一种可接受的方法直接从python引用它们?
注意:我知道我可以打开头文件并解析它,这很简单,但如果有更多的pythonic方式,我想使用它.
编辑:
这些是非常简单的#define,用于定义掩码中位的含义,例如:
#define FOO_A 0x3
#define FOO_B 0x5
Run Code Online (Sandbox Code Playgroud) 由于Python C级API的开发方式,许多内置函数和方法实际上没有参数的名称.
我发现它真的很烦人因为我无法通过查看文档来了解它.例如,eval
eval(表达式,globals = None,locals = None)
然后我写了这行代码
print(eval('a+b', globals={'a':1, 'b':2}))
Run Code Online (Sandbox Code Playgroud)
并得到了TypeError: eval() takes no keyword arguments.那么有这种功能的完整列表吗?如何知道函数是否允许包含关键字参数?
我使用 Python C API 用 C/C++ 创建了一个 Python 模块。我在 setup.py 中使用 setuptools.Extension 。
它创建一个 .py 文件,该文件从某些已编译的 .pyd 文件加载 python 模块:
def __bootstrap__():
global __bootstrap__, __loader__, __file__
import sys, pkg_resources, imp
__file__ = pkg_resources.resource_filename(__name__, 'zroya.cp36-win32.pyd')
__loader__ = None; del __bootstrap__, __loader__
imp.load_dynamic(__name__,__file__)
__bootstrap__()
Run Code Online (Sandbox Code Playgroud)
但它不会为 IDE 自动完成功能生成 python 存根。我希望所有导出的函数和类都可以从 .py 文件中可见:
def myfunction_stub(*args, **kwargs):
"""
... function docstring
"""
pass
Run Code Online (Sandbox Code Playgroud)
是否可以?或者我是否必须创建一些 python“预处理器”来从 .pyd 文件加载数据并生成带有文档字符串的存根?
源代码可在github上获取。
我想检查一个对象是否是某个类的实例。在 Python 中,我可以使用isinstance(obj, cls). 在 C/C++ 中,我发现了一个名为PyObject_IsInstance的函数。但它似乎不起作用isinstance。
详细(也称为下面的示例代码):
My。类型定义为MyType,对象定义为MyObject。MyType到名为 name 的导出模块My。my = My(),并isinstance(my, My)返回True。PyObject_IsInstance(my, (PyObject*)&MyType)检查my,并且返回0,这意味着my不是由定义的类的实例MyType。完整的C++代码:
#define PY_SSIZE_T_CLEAN
#include <python3.6/Python.h>
#include <python3.6/structmember.h>
#include <stddef.h>
typedef struct {
PyObject_HEAD
int num;
} MyObject;
static PyTypeObject MyType = []{
PyTypeObject ret = {
PyVarObject_HEAD_INIT(NULL, …Run Code Online (Sandbox Code Playgroud) 我正在努力如何在 Python C API 中创建 python Enum 对象。enum 类已赋值tp_base给PyEnum_Type,因此它继承了 Enum 。但是,我无法找到一种方法来告诉 Enum 基类枚举中有哪些项目。我想允许使用__members__每个 Python 枚举提供的属性从 Python 进行迭代和查找。
谢谢你,
耶勒
python-c-api ×10
python ×8
c ×4
python-3.x ×3
arguments ×1
c++ ×1
numpy ×1
performance ×1
structure ×1
types ×1
vector ×1