C与python的调用一(导入python模块与,获得函数与类)

python是一门很优秀的脚本语言,语法简洁而清晰,具有丰富和强大的类库。它常被昵称为胶水语言,它能够很轻松的把用其他语言制作的各种模块。 但是python的界面设计我们并不是很熟悉(虽然他也有很多很好的且功能强大的类库,例如wxpython等,但是相比其他的GUI设计,我们可能更加 熟悉QT或者MFC,因此不太会选用python作为界面设计的工具),所以我们在很多情况下,很难在有界面需求的项目中使用python的GUI去设 计。但是这样并不意味着我们不能依靠python的高效,简洁去做一些东西,我们可以用python做一些模块,然后再其他的编程语言中去调用她,下面就 举例一些相关的函数。

如果你在C代码中去调用python,那么你首先要做到就是初始化python环境。具体使用的函数如下为Py_Initialize()。当你 正确的将python环境初始化之后,就可以用最简单的一个CPython接口去跑一些脚本,该函数为PyRun_SimpleString(s),这个 函数大家一看就知道是用来干啥的了吧。使用该函数能够让你直接在参数里面写一些python,然后python环境就会调用这个函数,完成你所写的 python语句。例如PyRun_SimpleString("import tree"),使用这个语句,就能在C环境中使用python加载了 tree.py这个模块。

接下来,我们就要获得模块中定义的一些函数,大家知道,python里面的模块里面会定义很多的函数,类。当我们在python中对相关模块进行 import之后就能够直接调用了,那么我们在C中要如何获得这些函数、类呢?这些函数,类又是些什么东西呢。这就涉及到python的一些基本机制了, 其实在python里面,一切的东西都是对象,他们有共同的基类PyObject,至于这个PyObject具体是什么,这里就不展开了。因此我们可以得 出一些思路,那既然一切都是PyObject,那么我们在C里面使用PyObject将函数与类接进来不就好了。

现在让我们回到我们运行了PyRun_SimpleString("import tree"),此时我们已经在运行环境中加载了tree.py这个模块 了,那这个模块又是什么呢。根据上文,大家应该能猜到,没错,这个模块也是个以PyObject为基类的对象。此时对应的函数为 (PyObject *) PyImport_ImportModule(const char *name)或者 (PyObject *) PyImport_Import(PyObject *name)(两者的区别为,如果使用后者,你需要将模块的名称(通常是 char*)转换成PyObject对象),此时你就会得到一个类型为PyObject的moudle对象。

对于这个moudle对象,这里就不卖关子了,它实际上是一个python中的特殊的dict对象,里面有各种包含了这个moudle中的所有的类函数等 信息。因此,从这个moudle中获得相关的类和函数就是手到擒来的事情了。首先我们将这个moudle返回成一个dict对象,使用的函数为 (PyObject *) PyModule_GetDict(PyObject *)然后就使用 (PyObject *) PyDict_GetItemString(PyObject *dp, const char *key)来获得相关的函数 与类。如果是类的话,那获得的只是一个类定义,我们还需要将其构造成对象,使用的接口为 (PyObject *) PyInstance_New(PyObject *, PyObject *,PyObject *)具体的函数这里就不展 开了,大家网上找找吧。

下面是网上的一个代码,比较详细的说了这一系列过程,大家可以试一试,源网址找不到了,悲剧,就直接贴代码了:

def hello(s):

print "hello world"

print s

def arg(a, b):

print ‘a=‘, a

print ‘b=‘, b

return a + b

class Test:

def __init__(self):

print "init"

def say_hello(self, name):

print "hello,", name

return name

// pytest.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#include <Python.h>

int main(int argc, char* argv[])

{

//初始化python

Py_Initialize();

//定义python类型的变量

PyObject *pModule = NULL;

PyObject *pFunc = NULL;

PyObject *pArg = NULL;

PyObject *result = NULL;

PyObject *pClass = NULL;

PyObject *pInstance = NULL;

PyObject *pDict = NULL;

//直接运行python代码

PyRun_SimpleString("print ‘python start‘");

//引入模块

pModule = PyImport_ImportModule("test_code");

//获取模块字典属性

pDict = PyModule_GetDict(pModule);

//直接获取模块中的函数

pFunc = PyObject_GetAttrString(pModule, "hello");

//参数类型转换,传递一个字符串。将c/c++类型的字符串转换为python类型,元组中的python类型查看python文档

pArg = Py_BuildValue("(s)", "hello charity");

//调用直接获得的函数,并传递参数

PyEval_CallObject(pFunc, pArg);

//从字典属性中获取函数

pFunc = PyDict_GetItemString(pDict, "arg");

//参数类型转换,传递两个整型参数

pArg = Py_BuildValue("(i, i)", 1, 2);

//调用函数,并得到python类型的返回值

result = PyEval_CallObject(pFunc, pArg);

//c用来保存c/c++类型的返回值

int c;

//将python类型的返回值转换为c/c++类型

PyArg_Parse(result, "i", &c);

//输出返回值

printf("a+b=%d\n", c);

//通过字典属性获取模块中的类

pClass = PyDict_GetItemString(pDict, "Test");

//实例化获取的类

pInstance = PyInstance_New(pClass, NULL, NULL);

//调用类的方法

result = PyObject_CallMethod(pInstance, "say_hello", "(s)", "charity");

//输出返回值

char* name=NULL;

PyArg_Parse(result, "s", &name);   //这个函数的第二个参数相当扯淡,具体看下文的英文,类型使用字符来表示的,例如“s”代表

//str "i" 代表int,个人感觉相当扯淡

printf("%s\n", name);

PyRun_SimpleString("print ‘python end‘");

//释放python

Py_Finalize();

getchar();

return 0;

}

运行结果:

python start

hello world

hello charity

a= 1

b= 2

a+b=3

init

hello, charity

charity

python end

时间: 2024-10-19 09:55:22

C与python的调用一(导入python模块与,获得函数与类)的相关文章

Python 3.6.5 导入pymysql模块出错:No module named &#39;pymysql&#39;

检查一下项目设置中的解释器. 查看是否添加PyMySQL模块,如果没有请添加PyMySQL模块 Python 3.6.5 导入pymysql模块出错:No module named 'pymysql' 原文地址:https://www.cnblogs.com/zhan1995/p/8920369.html

Python 3.6.4 导入pymysql模块出错:No module named &#39;pymysql&#39;怎么办

遇到这个问题,还需要检查一下项目设置中的解释器. 如果未发现这个模块,可以添加一下. Python 3.6.4 导入pymysql模块出错:No module named 'pymysql'怎么办 原文地址:https://www.cnblogs.com/cgys/p/9000342.html

python交互环境中导入文件中自定义的函数报错

今天在学习python自定义函数时,遇到一个问题:我用notepad++编辑器自定义的函数,在交互环境下使用from 文件名 import 函数名 导入时,一直报错,检查了好几遍,一直报这个错: 代码如下: # -*-coding:utf-8 -*- #自定义函数 def 函数名(参数1,参数2...): 然后在缩进体内编写函数体,用return返回值 #自定义求绝对值函数 #def my_abs(x): #如果参数类型不是int或者float,会抛出类型错误异常 # if not isinst

Python相对、绝对导入浅析

这篇文章从另外一个不同的视角来分析一下Python的import机制,主要的目的是为了搞懂import中absolute.relative import遇到的几个报错. 这里不同的视角是指从Python import hooks这个方面来展开,当然本身关于Python import hooks有很多的文章,我这里不打算展开聊这个方面的内容,文章中主要会结合代码和PEP 302 – New Import Hooks这个PEP. 1. 几个跟import相关模块属性 首先我们需要了解几个跟impor

python导入自定义模块和包

参考资料 https://blog.csdn.net/gvfdbdf/article/details/52084144 http://www.runoob.com/python/python-modules.html python基本概念 python模块 Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句. 模块让你能够有逻辑地组织你的 Python 代码段. 把相关的代码分配到一个模块里能让你的代码更好用,更易懂

用Python玩转数据:python的函数、模块和包

Python函数 函数可以看成类似于数学中的函数,完成一个特定功能的一段代码. -绝对值函数 abs() -类型函数 type() -四舍五入函数 round() Python中有很多内建函数,即不需要另外导入的函数. -cmp(), str() 和 type()适用于所有标准类型.以下是数值型内建函数和实用内建函数. >>> dir(_builtins_) 命令可以看到Python中的内建变量和内建函数. >>> help(abs) 命令用于查看abs函数的帮助信息.

Python学习进程(12)模块

    模块让你能够有逻辑地组织你的Python代码段.     (1)python模块: 模块化的好处: 1.把相关的代码分配到一个模块里能让你的代码更好用,更易懂. 2.模块也是Python对象,具有随机的名字属性用来绑定或引用. 3.简单地说,模块就是一个保存了Python代码的文件.模块能定义函数,类和变量.模块里也能包含可执行的代码. 模块化的实例: [email protected]:/home/sunjimeng/桌面# cat first.py def ten(): for in

Python基础笔记系列十:模块

本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! 模块 #1.类比于java中的jar包,模块能让你能够有逻辑地组织你的Python代码段.#2.把相关的代码分配到一个模块里能让你的代码个更好用,更易懂.#3.模块也是Python对象,具有随机的名字属性用来绑定或引用.#4.简单来说,模块就是一个保存了Python代码的文件.模块能自定义函数,类和变量.模块里也能包含可执行的代码. 模块引入python提供了很多第三方的

Python 全栈开发八 日志模块

日志是一种可以追踪某些软件运行时所发生事件的方法.软件开发人员可以向他们的代码中调用日志记录相关的方法来表明发生了某些事情.一个事件可以用一个可包含可选变量数据的消息来描述.此外,事件也有重要性的概念,这个重要性也可以被称为严重性级别(level). 1.日志的作用 通过log的分析,可以方便用户了解系统或软件.应用的运行情况:如果你的应用log足够丰富,也可以分析以往用户的操作行为.类型喜好.地域分布或其他更多信息:如果一个应用的log同时也分了多个级别,那么可以很轻易地分析得到该应用的健康状

Python之日志处理(logging模块)

本节内容 日志相关概念 logging模块简介 使用logging提供的模块级别的函数记录日志 logging模块日志流处理流程 使用logging四大组件记录日志 配置logging的几种方式 向日志输出中添加上下文信息 参考文档 一.日志相关概念 日志是一种可以追踪某些软件运行时所发生事件的方法.软件开发人员可以向他们的代码中调用日志记录相关的方法来表明发生了某些事情.一个事件可以用一个可包含可选变量数据的消息来描述.此外,事件也有重要性的概念,这个重要性也可以被称为严重性级别(level)