python编辑器推荐使用python tools for visual studio ,个人感觉是最好用的Python编辑工具,比Wing之类的好用多了。
VPTS打开使用Wing编辑过的py文件,如果编辑任何代码都提示语法错误,是因为python不允许同时使用tab和空格进行格式对齐。(老子鄙视任何一切使用table进行对齐的程序员,你他妈没做过跨平台,就不知道有多坑爹)
VS默认的是使用4个空格代替tab建的,要想保留tab制表符,需要到选项 >> 文本编辑器中修改为保留制表符。
如果出现空格和table混用,使用快捷键 CTRL+R,CTRL+W 来切换空格的显示状态,删除不需要的符号
1.读取python文件位置
程序最终发布的时候,不需要在客户端机上安装python,只需要拷贝python文件的libs,lib库,include文件夹,dll文件夹等到安装目录下,并使用
Py_SetPythonHome((char*)strPythonLibPath.c_str());指定查找路径
2.C++调用python函数
PyArg_ParseTuple和PyArg_Parse的区别
PyArg_ParseTuple 的返回值为元组,返回多个元素
PyArg_Parse 返回值只有一个元素
3. C++调用python
Py_Initialize(); //使用python之前,要调用Py_Initialize();这个函数进行初始化
PyRun_SimpleString( "import sys" );
PyRun_SimpleString( "sys.path.append( '../pythonparser/' )" );
PyRun_SimpleString( "print sys.path" );
PyRun_SimpleString( "print '------------------------------------'" );
PyObject *pName, *pModule, *pDict, *pFunc, *pArg, *pRetVal;
pModule = PyImport_ImportModule("fishtest");
pFunc = PyObject_GetAttrString(pModule,"getstudent");
pDict = PyModule_GetDict(pModule);
PyCallable_Check(pFunc);
char* pStuName;
int iBufferSize = 0;
int iAge = 0;
char *pSex = NULL;
char* pClass;
PyObject* pResult = PyEval_CallObject(pFunc, NULL);
int iLen = 0;
//"(s#is)s" #返回字符串长度,不带结束符 ()表示元组
//注意字符串不需要上级开辟空间
int iRes = PyArg_ParseTuple(pResult, "(s#is)s", &pStuName, &iLen, &iAge, &pSex, &pClass);
if (pResult && iRes)
{
cout << "Class:" << pClass << " " << pStuName << " " << pSex << endl;
}
Py_DECREF(pResult);
Py_DECREF(pFunc);
pArg = Py_BuildValue("(i, i, i)", 5, 6, 2);
pFunc = PyObject_GetAttrString(pModule,"FishSum");
PyObject* pResult1 = PyEval_CallObject(pFunc, pArg);
int c = 0;
PyArg_Parse(pResult1, "i", &c);
int iValue = PyInt_AS_LONG(pResult1);
Py_DECREF(pResult1);
Py_DECREF(pResult1);
Py_Finalize(); //调用Py_Finalize,这个和Py_Initialize相对应的.
return 0;
获取python异常的代码行和所在文件
def tableparser(server, strkey, htmltext):
restext = ''
try:
restext = tableparserEx(server, strkey, htmltext)
except Exception , e:
exc_type, exc_value, exc_traceback = sys.exc_info()
errinfo = exc_traceback.tb_next
while(errinfo): #进入到最内层出错的函数模块
strerr = 'errorinfo: '
strerr = strerr + " filename: " + errinfo.tb_frame.f_code.co_filename
strerr = strerr + " functionname: " + errinfo.tb_frame.f_code.co_name
strerr = strerr + " lineno: " + str(errinfo.tb_lineno)
errinfo = errinfo.tb_next
logging.debug(strerr)
logtext = strkey + ": " + restext
logging.debug(logtext)
return restext
3. 关于无法找到python27_d.lib等错误,参见 http://blog.sina.com.cn/s/blog_6247e9d50102uyp3.html,很详细
4.c++多线程调用python崩溃
(这一段是抄的)
python多线程在应用的时候有不少的事情需要重点的注意。其实只要掌握这些相关的技术段就能保证这个应用的完整。下面我们来看看具体是需要如何进行操作。
今天看了近一天关于多线程的应用中,如何安全调用python多线程方面的资料,开始的时候看的简直头大如斗,被python语言的全局锁(Global Interpreter Lock)、线程状态(Thread State )等都有点绕晕了,后来经过各方面文章和帮助文档的相互参考,发现对于2.4/2.5版本,提供了PyGILState_Ensure, PyGILState_Release,哎,这下可方便大发了。
一、首先定义一个封装类,主要是保证PyGILState_Ensure, PyGILState_Release配对使用,而且这个类是可以嵌套使用的。
- #include <python.h>
- class PyThreadStateLock
- {
- public:
- PyThreadStateLock(void)
- {
- state = PyGILState_Ensure( );
- }
- ~PyThreadStateLock(void)
- {
- PyGILState_Release( state );
- }
- private:
- PyGILState_STATE state;
- };
二、在主线程中,这样处理
// 初始化
Py_Initialize();
// 初始化线程支持
PyEval_InitThreads();
// 启动子线程前执行,为了释放PyEval_InitThreads获得的全局锁,否则子线程可能无法获取到全局锁。
PyEval_ReleaseThread(PyThreadState_Get());
// 其他的处理,如启动子线程等
......
// 保证子线程调用都结束后
PyGILState_Ensure();
Py_Finalize();
// 之后不能再调用任何python的API