Python C-API......如何用C语言编写Python代码[英] Python C-API… how to write python code in C

本文是小编为大家收集整理的关于Python C-API......如何用C语言编写Python代码的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我有以下python代码…并想在… python - c - api

中编写此代码.
from enum import Enum
class MqWaitOnEventE(Enum):                                                                                        
  NO  = 0
  ONCE = 1
  FOREVER = 2

感谢您的帮助.

首先方法

// enum definition 
PyObject *enumModO=NULL, *enumDictO=NULL, *intEnumO=NULL;                                                              
LngErrorCheckN(enumModO   = PyImport_ImportModule("enum"));                                                            
LngErrorCheckN(enumDictO  = PyModule_GetDict(enumModO));                                                               
LngErrorCheckN(intEnumO   = PyDict_GetItemString(enumDictO,"IntEnum"));                                                

// get 'MqWaitOnEventE '
PyObject *dictMqWaitOnEventE = NULL, *result=NULL, *base=NULL;                                                         
LngErrorCheckN(dictMqWaitOnEventE = PyDict_New());                                                                     
LngErrorCheck(PyDict_SetItemString (dict, "__module__", PyUnicode_FromString("pymsgque")));                            
LngErrorCheck(PyDict_SetItemString (dict, "NO",         OT_NEW_INT_OBJ(MQ_WAIT_NO)));                                  
LngErrorCheck(PyDict_SetItemString (dict, "ONCE",       OT_NEW_INT_OBJ(MQ_WAIT_ONCE)));                                
LngErrorCheck(PyDict_SetItemString (dict, "FOREVER",    OT_NEW_INT_OBJ(MQ_WAIT_FOREVER)));                             
LngErrorCheckN(base = PyTuple_Pack(1, intEnumO));                                                                      
LngErrorCheckN(result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO","MqWaitOnEventE", base, dictMqWaitOnEventE));                                   

以以下错误结尾…

Traceback (most recent call last):
  File "…/MyServer.py", line 14, in <module>
    import pymsgque
  File "…/python3.7/enum.py", line 151, in __new__
    enum_members = {k: classdict[k] for k in classdict._member_names}
AttributeError: 'dict' object has no attribute '_member_names'

这是什么? …Python是否需要SOM internals ?

推荐答案

这是C模块初始化文件中A Enum 的类型安全解决方案…

  • MqBuffer…是我的字符串缓冲区类
  • NS(…)是创建一个唯一名称空间的宏…我将其用于所有C-Exextern对象 .

示例将在模块名称空间中创建新的 mqslavee 类.

PyObject* m = PyModule_Create(&ModuleDef);
...

MQ_BUF buf = MqBufferCreate(1000);
MqBufferAppendC(buf,"from enum import IntEnum\n");
MqBufferAppendC(buf,"class MqSlaveE(IntEnum):\n");
MqBufferAppendV(buf,"  LOOPBACK = %i\n", MQ_SLAVE_LOOPBACK);
MqBufferAppendV(buf,"  OTHER    = %i\n", MQ_SLAVE_OTHER);
MqBufferAppendV(buf,"  FILTER   = %i\n", MQ_SLAVE_FILTER);
MqBufferAppendV(buf,"  MASTER   = %i\n", MQ_SLAVE_MASTER);
MqBufferAppendV(buf,"  USER     = %i\n", MQ_SLAVE_USER);

PyObject *g, *dl, *dg, *v;
MQ_CST script = MqBufferGetC_e(buf);
g = PyImport_AddModule("__main__");
dg = PyModule_GetDict(g);
dl = PyModule_GetDict(m);
LngErrorCheckN(v = PyRun_String(script, Py_file_input, dg, dl));
Py_DECREF(v);

NS(MqSlaveE) = PyDict_GetItemString(dl,"MqSlaveE");

MqBufferDelete(&buf);
return m;

to 检查对象和提取我使用proc…

的值
enum MqErrorE NS(Get_Enum_FromObj) (PyObject *enumT, PyObject *enumE, MQ_INT *ret) {                               
  if (!PyObject_IsInstance(enumE, enumT)) {                                                                        
    PyErr_Format(PyExc_TypeError,                                                                                  
        "input_enum_type = '%s' is not the required_enum_type = '%s'",                                             
                    Py_TYPE(enumE)->tp_name,     ((PyTypeObject*)enumT)->tp_name                                   
    );                                                                                                             
    return MQ_ERROR;                                                                                               
  }                                                                                                                
  return PyObj_AsINT(enumE,ret);                                                                                   
} 

本文地址:https://www.itbaoku.cn/post/1937823.html

问题描述

I have the following python code… and want to write this Code in… Python-C-API

from enum import Enum
class MqWaitOnEventE(Enum):                                                                                        
  NO  = 0
  ONCE = 1
  FOREVER = 2

Thanks for help.

FIRST approach

// enum definition 
PyObject *enumModO=NULL, *enumDictO=NULL, *intEnumO=NULL;                                                              
LngErrorCheckN(enumModO   = PyImport_ImportModule("enum"));                                                            
LngErrorCheckN(enumDictO  = PyModule_GetDict(enumModO));                                                               
LngErrorCheckN(intEnumO   = PyDict_GetItemString(enumDictO,"IntEnum"));                                                

// get 'MqWaitOnEventE '
PyObject *dictMqWaitOnEventE = NULL, *result=NULL, *base=NULL;                                                         
LngErrorCheckN(dictMqWaitOnEventE = PyDict_New());                                                                     
LngErrorCheck(PyDict_SetItemString (dict, "__module__", PyUnicode_FromString("pymsgque")));                            
LngErrorCheck(PyDict_SetItemString (dict, "NO",         OT_NEW_INT_OBJ(MQ_WAIT_NO)));                                  
LngErrorCheck(PyDict_SetItemString (dict, "ONCE",       OT_NEW_INT_OBJ(MQ_WAIT_ONCE)));                                
LngErrorCheck(PyDict_SetItemString (dict, "FOREVER",    OT_NEW_INT_OBJ(MQ_WAIT_FOREVER)));                             
LngErrorCheckN(base = PyTuple_Pack(1, intEnumO));                                                                      
LngErrorCheckN(result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO","MqWaitOnEventE", base, dictMqWaitOnEventE));                                   

end with following error…

Traceback (most recent call last):
  File "…/MyServer.py", line 14, in <module>
    import pymsgque
  File "…/python3.7/enum.py", line 151, in __new__
    enum_members = {k: classdict[k] for k in classdict._member_names}
AttributeError: 'dict' object has no attribute '_member_names'

what is this? … does python require som internals from me ?

推荐答案

This is the type-safe solution for a enum in C-Module initialization file…

  • MqBuffer… is my string buffer class
  • NS(…) is a macro to create a unique namespace… I use this for all c-extern objects .

the example will create the new MqSlaveE class in the module namespace.

PyObject* m = PyModule_Create(&ModuleDef);
...

MQ_BUF buf = MqBufferCreate(1000);
MqBufferAppendC(buf,"from enum import IntEnum\n");
MqBufferAppendC(buf,"class MqSlaveE(IntEnum):\n");
MqBufferAppendV(buf,"  LOOPBACK = %i\n", MQ_SLAVE_LOOPBACK);
MqBufferAppendV(buf,"  OTHER    = %i\n", MQ_SLAVE_OTHER);
MqBufferAppendV(buf,"  FILTER   = %i\n", MQ_SLAVE_FILTER);
MqBufferAppendV(buf,"  MASTER   = %i\n", MQ_SLAVE_MASTER);
MqBufferAppendV(buf,"  USER     = %i\n", MQ_SLAVE_USER);

PyObject *g, *dl, *dg, *v;
MQ_CST script = MqBufferGetC_e(buf);
g = PyImport_AddModule("__main__");
dg = PyModule_GetDict(g);
dl = PyModule_GetDict(m);
LngErrorCheckN(v = PyRun_String(script, Py_file_input, dg, dl));
Py_DECREF(v);

NS(MqSlaveE) = PyDict_GetItemString(dl,"MqSlaveE");

MqBufferDelete(&buf);
return m;

to check the object and extract the value I use a proc…

enum MqErrorE NS(Get_Enum_FromObj) (PyObject *enumT, PyObject *enumE, MQ_INT *ret) {                               
  if (!PyObject_IsInstance(enumE, enumT)) {                                                                        
    PyErr_Format(PyExc_TypeError,                                                                                  
        "input_enum_type = '%s' is not the required_enum_type = '%s'",                                             
                    Py_TYPE(enumE)->tp_name,     ((PyTypeObject*)enumT)->tp_name                                   
    );                                                                                                             
    return MQ_ERROR;                                                                                               
  }                                                                                                                
  return PyObj_AsINT(enumE,ret);                                                                                   
} 
相关标签/搜索