Linux_python环境部署
使用设备:Orange Pi Zero2
6步即成:
1.通过以下命令更新系统并安装编译 Python 所需的环境:
sudo apt update
sudo apt install -y build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libsqlite3-dev libreadline-dev libffi-dev curl libbz2-dev
2.下载 Python 3.9.10 源码并解压:(手动下载推到linux亦可)
wget https://www.python.org/ftp/python/3.9.10/Python-3.9.10.tgz
tar xvf Python-3.9.10.tgz
3.配置并编译 Python:
cd Python-3.9.10
./configure --enable-optimizations
make -j4
sudo make install
4.完成安装后,建立软连接以便系统可以找到新安装的 Python 3.9:
sudo rm -f /usr/bin/python
sudo ln -s /usr/local/bin/python3.9 /usr/bin/python
5.更新 pip 并更换 pip 源以加快 Python 库的安装速度:
sudo apt install -y python-pip python3-pip
mkdir -p ~/.pip
vim ~/.pip/pip.conf
6.在 pip.conf 文件中添加以下内容:
[global]
timeout = 6000
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
trusted-host = pypi.tuna.tsinghua.edu.cn
C语言调用Python,传参/获取返回值
涉及到的Python相关函数:
Py_Initialize():初始化Python解释器。
Py_IsInitialized():检查Python解释器是否成功初始化。
PyRun_SimpleString():执行一段Python代码。在这里使用该函数导入sys模块和添加当前路径到sys.path列表中。
PyObject:是Python对象的基本结构体类型。
PyString_FromString():将一个C字符串转换为Python字符串对象。
PyImport_Import():根据给定的字符串名字加载一个Python模块。
PyModule_GetDict():获取一个模块对象的字典属性。
PyDict_GetItemString():从字典中获取指定键的值。
PyCallable_Check():检查一个对象是否可调用(即函数)。
PyTuple_New():创建一个新的元组对象。
Py_BuildValue():构造一个适当的Python对象。
PyTuple_SetItem():将指定的对象插入到元组中的指定位置。
PyObject_CallObject():调用指定的Python对象,并传递参数。
PyArg_Parse():从Python对象中解析出C类型的值。
PyErr_Print():打印出Python异常信息。
Py_DECREF():减少Python对象的引用计数。
Py_Finalize():关闭Python解释器。
demo:python程序
# py_add #
def add(a=1,b=1):
print('Function of python called!')
print('a = ',a)
print('b = ',b)
print('a + b = ',a+b)
return "a + b = %d" % (a+b)
demo:C 调用python
// gcc -I/usr/include/python2.7/ mian.c -o main -L/usr/lib/ -lpython2.7
// 此程序名为:main.c
#include <stdio.h>
#include <stdlib.h>
#include <Python.h>
int main(int argc, char **argv)
{
// 初始化,载入python的扩展模块
Py_Initialize();
// 判断初始化是否成功
if (!Py_IsInitialized())
{
printf("Python init failed!\n");
return -1;
}
// PyRun_SimpleString 为宏,执行一段python代码
// 导入当前路径
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
// // PyRun_SimpleString("import sys");:
// 这行代码执行了Python的import sys语句,
// 将sys模块导入到当前的Python解释器中。
// sys模块提供了与Python解释器相关的功能和操作。
// // PyRun_SimpleString("sys.path.append('./')");:
// 这行代码执行了sys.path.append('./')语句,
// 将当前路径(./)添加到sys模块的path列表中。
// sys.path是一个Python列表,
// 包含了解释器在搜索模块时要查找的目录,
// 添加当前路径可以确保解释器能够找到位于当前路径下的模块文件。
PyObject *pName = NULL;
PyObject *pModule = NULL;
PyObject *pDict = NULL;
PyObject *pFunc = NULL;
PyObject *pArgs = NULL;
// 加载名为py_add的python脚本 = pName
pName = PyString_FromString("py_add");
pModule = PyImport_Import(pName);
if (!pModule)
{
printf("Load py_add.py failed!\n");
getchar();
return -1;
}
pDict = PyModule_GetDict(pModule);
if (!pDict)
{
printf("Can't find dict in py_add!\n");
return -1;
}
//把python里的 add 函数调出,用pFunc承接
pFunc = PyDict_GetItemString(pDict, "add");
if (!pFunc || !PyCallable_Check(pFunc))
{
printf("Can't find function!\n");
getchar();
return -1;
}
/*
向Python传参数是以元组(tuple)的方式传过去的,
因此我们实际上就是构造一个合适的Python元组就
可以了,要用到PyTuple_New,Py_BuildValue,PyTuple_SetItem等几个函数
*/
//传两个参数给python里的函数
pArgs = PyTuple_New(2);
// PyObject* Py_BuildValue(char *format, ...)
// 把C++的变量转换成一个Python对象。当需要从
// C++传递变量到Python时,就会使用这个函数。此函数
// 有点类似C的printf,但格式不同。常用的格式有
// s 表示字符串,
// i 表示整型变量, 如Py_BuildValue("i",123,456)
// f 表示浮点数,
// O 表示一个Python对象
// 确定两个参数的值
PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 123));
PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 321));
//调用python的add函数并获取返回值
PyObject *pValue = PyObject_CallObject(pFunc, pArgs);
if (!pValue)
{
PyErr_Print();
printf("Error: function call failed\n");
}
//将返回值转换为C类型
char *result = NULL;
if (!PyArg_Parse(pValue, "s", &result))
{
PyErr_Print();
printf("Error: parse failed\n");
}
//打印python函数的返回值;
printf("get result:%s\n",result);
// 清理python对象
if (pName)
{
Py_DECREF(pName);
}
if (pArgs)
{
Py_DECREF(pArgs);
}
if (pModule)
{
Py_DECREF(pModule);
}
// 关闭python调用
Py_Finalize();
return 0;
}