Python 3.0中的C API已经更改(不建议使用)文件对象的许多功能.
之前,在2.X中,您可以使用
PyObject* PyFile_FromString(char *filename, char *mode)
Run Code Online (Sandbox Code Playgroud)
创建Python文件对象,例如:
PyObject *myFile = PyFile_FromString("test.txt", "r");
Run Code Online (Sandbox Code Playgroud)
...但是Python 3.0中不再存在这样的功能.什么是Python 3.0相当于这样的调用?
我已经阅读了Python C-API的文档,甚至还编写了一些扩展模块.但是,在从C函数返回Python对象时,我仍然有点不清楚它的确切语义.
Python文档中的有限示例通常显示一个返回结果的C函数Py_BuildValue.现在,Py_BuildValue返回a New Reference,并将此引用的所有权转移给解释器.那么,我可以从中推断出一般规则是返回Python的任何对象必须是新引用,并且从C函数返回对象与将对象的所有权转移到解释器相同吗?
如果是这样,那么返回已经拥有某个东西的对象的情况又如何呢?例如,假设你编写一个C函数,它接受a PyObject*是a tuple,然后调用PyTuple_GetItem它并返回结果. PyTuple_GetItem返回一个借来的引用 - 意味着该项仍然由元组"拥有".那么,在将函数返回给解释器之前,返回结果的C函数PyTuple_GetItem是否有INCREF结果?
例如:
static PyObject* my_extension_module(PyObject* tup)
{
PyObject* item = PyTuple_GetItem(tup, 1);
if (!item) { /* handle error */ }
return item; // <--- DO WE NEED TO INCREF BEFORE RETURNING HERE?
}
Run Code Online (Sandbox Code Playgroud) 我有一个大量使用的c ++代码shared_ptr和STL.一个常见的标题说
#include<boost/shared_ptr.hpp>
using boost::shared_ptr; // for shared_ptr
using namespace std; // for STL
Run Code Online (Sandbox Code Playgroud)
我现在想切换到c ++ 0x来使用语言功能,使用gcc 4.6 -std=c++0x.然而std::shared_ptr现在也存在,导致未指明shared_ptr(boost::shared_ptrvs std::shared_ptr)的模糊性.
切换到std::shared_ptr相反时,如下所示:
#include<memory>
using namespace std; // for STL; also imports std::shared_ptr
Run Code Online (Sandbox Code Playgroud)
然后我遇到了问题boost::python,它boost::shared_ptr只是有效地工作(至少没有进一步的摆弄):
/usr/include/boost/python/object/make_ptr_instance.hpp:30:52: error: no matching function for call to 'get_pointer(const std::shared_ptr<Cell>&)'
Run Code Online (Sandbox Code Playgroud)
我的问题是
boost::shared_ptr和std::shared_ptr(比不使用的C++ 0x现在其他),并且还boost::shared_ptr最终只是一个别名std::shared_ptr; 这将自动解决我的问题.谢谢!
我试图理解Python C-Api是如何工作的,我想在Python和C Extension之间交换numpy数组.
所以,我开始了这个教程:http://dsnra.jpl.nasa.gov/software/Python/numpydoc/numpy-13.html
试图在那里做第一个例子,计算2d numpy数组的跟踪的C模块对我来说非常整洁,因为我也想在2d数组中进行基本操作.
#include <Python.h>
#include "Numeric/arrayobject.h"
#include<stdio.h>
int main(){
Py_Initialize();
import_array();
}
static char doc[] =
"This is the C extension for xor_masking routine";
static PyObject *
trace(PyObject *self, PyObject *args)
{
PyObject *input;
PyArrayObject *array;
double sum;
int i, n;
if (!PyArg_ParseTuple(args, "O", &input))
return NULL;
array = (PyArrayObject *)
PyArray_ContiguousFromObject(input, PyArray_DOUBLE, 2, 2);
if (array == NULL)
return NULL;
n = array->dimensions[0];
if (n > array->dimensions[1])
n = array->dimensions[1];
sum = …Run Code Online (Sandbox Code Playgroud) 我将Python嵌入到将具有已定义API的C/C++应用程序中.
应用程序需要实例化脚本中定义的类,这些类的结构大致如下:
class userscript1:
def __init__(self):
##do something here...
def method1(self):
## method that can be called by the C/C++ app...etc
Run Code Online (Sandbox Code Playgroud)
我过去曾经管理过(为了概念验证)使用以下类型的代码完成这项工作:
PyObject* pName = PyString_FromString("userscript.py");
PyObject* pModule = PyImport_Import(pName);
PyObject* pDict = PyModule_GetDict(pModule);
PyObject* pClass = PyDict_GetItemString(pDict, "userscript");
PyObject* scriptHandle = PyObject_CallObject(pClass, NULL);
Run Code Online (Sandbox Code Playgroud)
现在我处于更多的生产环境中,这在PyImport_Import行失败了 - 我想这可能是因为我正在尝试将目录添加到脚本名称中,例如
PyObject* pName = PyString_FromString("E:\\scriptlocation\\userscript.py");
Run Code Online (Sandbox Code Playgroud)
现在,为了让您了解我尝试过的内容,我尝试在所有这些调用之前修改系统路径以使其搜索此模块.基本上尝试以编程方式修改sys.path:
PyObject* sysPath = PySys_GetObject("path");
PyObject* path = PyString_FromString(scriptDirectoryName);
int result = PyList_Insert(sysPath, 0, path);
Run Code Online (Sandbox Code Playgroud)
这些行运行正常,但对我的代码工作没有任何影响.显然,我的真实代码有一大堆错误检查,我已经排除了所以不要担心!
所以我的问题是:如何将嵌入式解释器适当地引导到我的脚本中以便我可以实例化类?
所以,我通常非常了解Python中的全局解释器锁(GIL)是如何工作的.本质上,当解释器正在运行时,一个线程将GIL保存为N个刻度(N可以使用设置sys.setcheckinterval),此时GIL被释放而另一个线程可以获取GIL.如果一个线程开始I/O操作,也会发生这种情况.
我有点困惑的是这一切是如何与C扩展模块一起工作的.
如果你有一个C扩展模块获取GIL,然后使用执行一些python代码PyEval_EvalCode,解释器是否可以释放GIL并将其提供给其他线程?或者获取GIL的C线程是否会永久保留GIL,直到PyEval_EvalCode返回并且GIL在C中明确释放?
PyGILState gstate = PyGILState_Ensure();
....
/* Can calling PyEval_EvalCode release the GIL and let another thread acquire it?? */
PyObject* obj = PyEval_EvalCode(code, global_dict, local_dict);
PyGILState_Release(gstate);
Run Code Online (Sandbox Code Playgroud) It seems that the Python C API is not consistent with the const correctness of character arrays. For example, PyImport_ImportFrozenModule accepts a char*, whereas PyImport_ImportModule accepts a const char*.
The implication of all this is that in my C++ application that I am writing with an embedded Python interpreter, I sometimes have to cast the string literal that I pass to a Python API call as just a char* (as opposed to const char*), and sometimes I …
我为Python包装了一些C代码,它可以工作.C模块创建一个句柄,我将其传递给Python PyCapsule.我想要的API可以用Python制作:
import wrapped
class Test(object):
def __init__(self, loc ):
self.handle = wrapped.new(loc)
def foo(self, data):
return wrapped.foo(self.handle, data)
所以这个问题更像是一个美容问题.我是否必须包装包装器,或者我可以将上面显示的代码移动到C代码中,即导出类而不是一堆函数?
我想创建一个带有嵌入式python解释器和基本调试功能的应用程序.现在我在API中搜索可用于逐步运行代码的函数,并获取正在(或即将执行)的当前代码行的编号.
在进行跟踪和分析时,官方Python文档对我来说似乎有点不足.例如,没有关于返回值含义的信息Py_tracefunc.
到目前为止,我已经汇总了以下内容:
#include <Python.h>
static int lineCounter = 0;
int trace(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg)
{
if(what == PyTrace_LINE)
{
lineCounter += 1;
printf("line %d\n", lineCounter);
}
return 0;
}
int main(int argc, char *argv[])
{
wchar_t *program = Py_DecodeLocale(argv[0], NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
exit(1);
}
Py_SetProgramName(program); /* optional but recommended */
Py_Initialize();
PyEval_SetTrace(trace, NULL);
char *code = …Run Code Online (Sandbox Code Playgroud) 我已经成功地使用cppyy为我正在研究的C++项目进行自动python绑定.我最近加入了Eigen库,但是我很难和cppyy一起使用它.有没有人有这方面的经验,或者知道我应该怎么做?
我有回购的以下结构(仅显示相关部分):
.
??? CMakeLists.txt
??? build
??? external
?? eigen
??? include
?? all .hpp files
??? src
?? all .cpp files
??? python
?? qmc.py
Run Code Online (Sandbox Code Playgroud)
这里external/eigen是Eigen GitHub回购的副本.该qmc.py文件是cppyy魔法发生的地方,它看起来像这样(在尝试添加Eigen之前,这个工作正常)
import cppyy
import tempfile
import os
import glob
try:
current_dir = os.path.dirname(__file__)
except NameError:
current_dir = os.getcwd()
source_dir = os.path.dirname(current_dir)
install_dir = os.path.join(source_dir, 'build')
include_dir = os.path.join(source_dir, 'include')
eigen_dir = os.path.join(source_dir, 'external', 'eigen')
print(current_dir, source_dir, include_dir, install_dir)
def cmake_run(build_type='Release', c_compiler='gcc', cxx_compiler='g++'): …Run Code Online (Sandbox Code Playgroud) python-c-api ×10
python ×9
c ×6
c++ ×3
python-3.x ×3
boost ×1
c++11 ×1
cpython ×1
eigen ×1
numpy ×1
python-2.7 ×1
shared-ptr ×1