给定一个内置的四元数数据类型,如何将四元数的 numpy 数组视为具有大小为 4 的额外维度的浮点数 numpy 数组(不复制内存)?
Numpy 内置了对浮点数和复杂浮点数的支持。我需要使用四元数——它概括了复数,但它们不是有两个分量,而是有四个分量。已经有一个非常好的包,它使用 C API 将四元数直接合并到 numpy 中,它似乎可以非常快地完成所有操作。我还需要添加一些四元数函数,但我想我基本上可以处理这些。
但是,我还希望能够在我需要使用 Awesomenumba包编写的其他函数中使用这些四元数。不幸的是,numba 目前无法处理自定义类型。但我不需要那些 numba 函数中的奇特四元数函数;我只需要数字本身。所以我希望能够将四元数数组重新转换为具有一个额外维度(大小为 4)的浮点数数组。特别是,我想只使用数组中已有的数据而不进行复制,并将其视为新数组。我找到了PyArray_View函数,但不知道如何实现它。
(我非常有信心数据连续保存在内存中,我认为这是简单查看它们所必需的。具体来说,elsize = 8*4在alignment = 8四元数包中。)
我正在寻找使用 Python3 C API 来添加内置函数。我这样做只是为了帮助我熟悉 Python C API 的练习。这个问题的答案很好地解释了为什么人们可能不想这样做。无论如何,我想foo向Pythonbuiltins模块添加一个函数。
这是我到目前为止所做的( foo.c):
#include <Python.h>
#include <stdio.h>
static PyObject*
foo(PyObject *self, PyObject *args){
printf("foo called");
return Py_None;
}
char builtin_name[] = "builtins";
char foo_name[] = "foo";
char foo_doc[] = "foo function";
static PyMethodDef foo_method = {foo_name, foo, METH_NOARGS, foo_doc};
PyMODINIT_FUNC
PyInit_foo(void){
PyObject *builtin_module = PyImport_ImportModule(builtin_name);
PyModule_AddFunctions(builtin_module, &foo_method);
return builtin_module;
}
Run Code Online (Sandbox Code Playgroud)
我将其放置在Modules/Python 源目录中的目录中。
是否有可能pip install package提供可选的 C 扩展,但专门禁用编译这些扩展的过程?
此类包的示例如下:
我有一些代码尝试将对象解析为整数:
long val = PyLong_AsLong(obj);
if(val == -1 && PyErr_Occurred()) {
return -1;
}
Run Code Online (Sandbox Code Playgroud)
这obj是一个普通的PyObject *,并PyLong_AsLong引发一个非常通用的TypeErrorifobj不是整数。
我想将错误消息转换为更具信息性的内容,因此我想修改现有的错误对象,或者重新引发它。
我当前的解决方案是这样做:
long val = PyLong_AsLong(obj);
if(val == -1 && PyErr_Occurred()) {
PyErr_Clear();
PyErr_Format(PyExc_TypeError, "Parameter must be an integer type, but got %s", Py_TYPE(obj)->tp_name);
return -1;
}
Run Code Online (Sandbox Code Playgroud)
这是重新引发错误的正确方法吗?具体来说,
PyErr_Clear?我怀疑它正确地减少了现有的异常对象,但我不确定。raise new_err from old_err?我不确定如何PyErr_SetExcInfo在这种情况下使用,尽管我的直觉告诉我它可能在某种程度上相关。
我正在包装一个 C 库,该库在失败时返回有限数量的错误代码之一。当错误发生时,我想将错误代码添加为 C 异常的属性,以便 Python 代码可以检索它并将错误代码映射到人类可读的异常。这可能吗?
例如我想在Python层执行此操作:
try:
call_my_library_func()
except MyLibraryError as ex:
print("Error code was %s" % ex.code)
Run Code Online (Sandbox Code Playgroud)
我能达到的最接近但我不喜欢的方法是使用PyErr_SetObject
PyObject *tuple = PyTuple_New(2);
PyTuple_SetItem(tuple, 0, PyUnicode_FromString("Helpful error message"));
PyTuple_SetItem(tuple, 1, PyLong_FromLong(257));
//PyErr_SetString(MyLibraryError, "Helpful error message\n");
PyErr_SetObject(MyLibraryError, tuple);
Run Code Online (Sandbox Code Playgroud)
然后我可以这样做:
try:
call_my_library_func()
except MyLibraryError as ex:
message, code = ex.args[0], -1
if len(ex.args > 1):
code = ex.args[1]
Run Code Online (Sandbox Code Playgroud) 我有一个 C 函数,涉及使用 zstd 解压缩数据。我正在尝试使用 Cython 调用该函数。
使用文档中的此页面作为指南,我可以毫无问题地编译和运行下面的代码。
(我实际上并没有在这里使用 zstd lib)
// hello.c
#include <stdio.h>
#include <zstd.h>
int hello() {
printf("Hello, World!\n");
void *next_in = malloc(0);
void *next_out = malloc(0);
return 0;
}
# Hello.pyx
cdef extern from "hello.c":
int hello()
cpdef int callHello():
hello()
# hello_wrapper.setup.py
from setuptools import setup, Extension
from Cython.Build import cythonize
ext_modules = [
Extension(
"hello_wrapper",
["hello_wrapper.pyx"],
libraries=["zstd"],
library_dirs=["path/to/zstd/lib"],
include_dirs=['path/to/zstd/include'],
)
]
setup(
ext_modules = cythonize(ext_modules, gdb_debug=True)
)
Run Code Online (Sandbox Code Playgroud)
使用如下命令我得到预期的输出:
>py hello_wrapper.setup.py build_ext --inplace
>py …Run Code Online (Sandbox Code Playgroud) 我是 Python C-API 的新手。
目前我通过以下方式从嵌入式 Python 模块获取对象
PyObject* a = (PyObject*) PyObject_GetAttrString(pModule, "a");
std::cout << "a as long is " << PyLong_AsLong(a) << std::endl;
Run Code Online (Sandbox Code Playgroud)
我通过访问 numpy 对象
PyArrayObject* array = (PyArrayObject*) PyObject_GetAttrString(pModule, "A");
Run Code Online (Sandbox Code Playgroud)
如何测试该对象是否真的是 a PyArrayObject?换句话说,如何通过 Python 来做我想做的事情isinstance(a, numpy.ndarray)?
如何使用Python C API模拟以下Python函数?
def foo(bar, baz="something or other"):
print bar, baz
Run Code Online (Sandbox Code Playgroud)
(即,可以通过以下方式调用它:
>>> foo("hello")
hello something or other
>>> foo("hello", baz="world!")
hello world!
>>> foo("hello", "world!")
hello, world!
Run Code Online (Sandbox Code Playgroud)
)
我编写了一个嵌入Python的小程序.我正在使用Py_Initialize()和Py_Finalize()正确设置它,并且能够使用PyRun_SimpleString或PyRun_SimpleFile运行脚本.但是,我不知道在打印变量时如何模仿Python自己的解释器的行为.
特别:
a = (1, 2, 3)
print a
Run Code Online (Sandbox Code Playgroud)
适合我的工作:打印出来(1,2,3)
然而:
a = (1, 2, 3)
a
Run Code Online (Sandbox Code Playgroud)
什么都没有打印出来.在Python自己的解释器中,这也会打印出(1,2,3).如何让我的代码执行用户期望的操作并打印出值?
提前致谢!
我有一个变量PyObject,我知道是一个Python bool.它是True或False(例如.Py_True或Py_False).现在我想以某种方式将其转换为C++.
使用字符串执行此操作并不是很难,有一个辅助函数 - PyBytes_AsString将python字符串转换为C字符串.现在我需要像boolean那样的东西(或者因为boolC中没有,所以需要int ).
或者如果没有转换,也许某些功能可以与true或false进行比较?有点像int PyBool_IsTrue(PyObject*)?
以下是一些示例代码,可以更轻松地理解我需要的内容:
#include <Python.h>
int main()
{
/* here I create Python boolean with value of True */
PyObject *b = Py_RETURN_TRUE;
/* now that I have it I would like to turn in into C type so that I can determine if it's True or False */
/* something like */
if (PyBool_IsTrue(b))
{ /* it's true! …Run Code Online (Sandbox Code Playgroud) python ×10
python-c-api ×10
c ×4
python-3.x ×3
numpy ×2
cython ×1
dll ×1
exception ×1
interpreter ×1
pip ×1
setuptools ×1