首页 > 编程知识 正文

python如何调用canoe,python如何调用参数配置文件

时间:2023-12-27 22:27:13 阅读:325700 作者:HNEA

本文目录一览:

我会Python,且第三方系统有接口,我应该如何通过Python去调用第三方系统的接口,进行对接?

python因为良好的编码性和扩展库正被大规模的使用,但他有两个缺点:1、代码可见;2、执行效率低,于是在实际应用中经常会把高效和核心代码用C/C++实现,业务部分用python实现。这就需要进行混合编程,本文对python调用动态库的方法及注意事项进行记录

主题

python标准库函数中提供了调用动态库的包————ctypes

加载动态库

查找动态库ctypes.util.find_library

根据动态库调用方式的不同,可以分为cdecl和stdcall两种,这两种方式的主要区别见下表。后面的例子以cdecl调用方式为例,stdcall类同。

调用标准 内存栈维护者 函数名

cdecl 调用者 前面加下划线,后面加“@”符号和参数的字节数

stdcall 被调用者 在输出函数名前面加下划线

* ctypes加载动态库有两种方式。构造类对象libc = CDLL("libtestlib.dll")和实例化instancelibc = cdll.LoadLibrary("libtestlib.dll")。这两种方式都会返回一个动态库操作的句柄,

怎样让Python脚本与C++程序互相调用

二、Python调用C/C++

1、Python调用C动态链接库

Python调用C库比较简单,不经过任何封装打包成so,再使用python的ctypes调用即可。

(1)C语言文件:pycall.c

[html] view plain copy

/***gcc -o libpycall.so -shared -fPIC pycall.c*/

#include stdio.h

#include stdlib.h

int foo(int a, int b)

{

printf("you input %d and %dn", a, b);

return a+b;

}

(2)gcc编译生成动态库libpycall.so:gcc -o libpycall.so -shared -fPIC pycall.c。使用g++编译生成C动态库的代码中的函数或者方法时,需要使用extern "C"来进行编译。

(3)Python调用动态库的文件:pycall.py

[html] view plain copy

import ctypes

ll = ctypes.cdll.LoadLibrary

lib = ll("./libpycall.so")

lib.foo(1, 3)

print '***finish***'

(4)运行结果:

2、Python调用C++(类)动态链接库

需要extern "C"来辅助,也就是说还是只能调用C函数,不能直接调用方法,但是能解析C++方法。不是用extern "C",构建后的动态链接库没有这些函数的符号表。

(1)C++类文件:pycallclass.cpp

[html] view plain copy

#include iostream

using namespace std;

class TestLib

{

public:

void display();

void display(int a);

};

void TestLib::display() {

cout"First display"endl;

}

void TestLib::display(int a) {

cout"Second display:"aendl;

}

extern "C" {

TestLib obj;

void display() {

obj.display();

}

void display_int() {

obj.display(2);

}

}

(2)g++编译生成动态库libpycall.so:g++ -o libpycallclass.so -shared -fPIC pycallclass.cpp。

(3)Python调用动态库的文件:pycallclass.py

[html] view plain copy

import ctypes

so = ctypes.cdll.LoadLibrary

lib = so("./libpycallclass.so")

print 'display()'

lib.display()

print 'display(100)'

lib.display_int(100)

(4)运行结果:

3、Python调用C/C++可执行程序

(1)C/C++程序:main.cpp

[html] view plain copy

#include iostream

using namespace std;

int test()

{

int a = 10, b = 5;

return a+b;

}

int main()

{

cout"---begin---"endl;

int num = test();

cout"num="numendl;

cout"---end---"endl;

}

(2)编译成二进制可执行文件:g++ -o testmain main.cpp。

(3)Python调用程序:main.py

[html] view plain copy

import commands

import os

main = "./testmain"

if os.path.exists(main):

rc, out = commands.getstatusoutput(main)

print 'rc = %d, nout = %s' % (rc, out)

print '*'*10

f = os.popen(main)

data = f.readlines()

f.close()

print data

print '*'*10

os.system(main)

(4)运行结果:

4、扩展Python(C++为Python编写扩展模块)

所有能被整合或导入到其它python脚本的代码,都可以被称为扩展。可以用Python来写扩展,也可以用C和C++之类的编译型的语言来写扩展。Python在设计之初就考虑到要让模块的导入机制足够抽象。抽象到让使用模块的代码无法了解到模块的具体实现细节。Python的可扩展性具有的优点:方便为语言增加新功能、具有可定制性、代码可以实现复用等。

为 Python 创建扩展需要三个主要的步骤:创建应用程序代码、利用样板来包装代码和编译与测试。

(1)创建应用程序代码

[html] view plain copy

#include stdio.h

#include stdlib.h

#include string.h

int fac(int n)

{

if (n 2) return(1); /* 0! == 1! == 1 */

return (n)*fac(n-1); /* n! == n*(n-1)! */

}

char *reverse(char *s)

{

register char t, /* tmp */

*p = s, /* fwd */

*q = (s + (strlen(s) - 1)); /* bwd */

while (p q) /* if p q */

{

t = *p; /* swap move ptrs */

*p++ = *q;

*q-- = t;

}

return(s);

}

int main()

{

char s[BUFSIZ];

printf("4! == %dn", fac(4));

printf("8! == %dn", fac(8));

printf("12! == %dn", fac(12));

strcpy(s, "abcdef");

printf("reversing 'abcdef', we get '%s'n",

reverse(s));

strcpy(s, "madam");

printf("reversing 'madam', we get '%s'n",

reverse(s));

return 0;

}

上述代码中有两个函数,一个是递归求阶乘的函数fac();另一个reverse()函数实现了一个简单的字符串反转算法,其主要目的是修改传入的字符串,使其内容完全反转,但不需要申请内存后反着复制的方法。

(2)用样板来包装代码

接口的代码被称为“样板”代码,它是应用程序代码与Python解释器之间进行交互所必不可少的一部分。样板主要分为4步:a、包含Python的头文件;b、为每个模块的每一个函数增加一个型如PyObject* Module_func()的包装函数;c、为每个模块增加一个型如PyMethodDef ModuleMethods[]的数组;d、增加模块初始化函数void initModule()。

python 怎么调用odbc

入门

连接到数据库

调用connect方法并传入ODBC连接字符串,其会返回一个connect对象。通过connect对象,调用cursor()方法,可以获取一个游标cursor。如下代码示例:

import pyodbc

#连接示例: Windows系统, 非DSN方式, 使用微软 SQL Server 数据库驱动

cnxn =pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;PORT=1433;DATABASE=testdb;UID=me;PWD=pass')

#连接示例: Linux系统, 非DSN方式, 使用FreeTDS驱动

cnxn =pyodbc.connect('DRIVER={FreeTDS};SERVER=localhost;PORT=1433;DATABASE=testdb;UID=me;PWD=pass;TDS_Version=7.0')

#连接示例:使用DSN方式

cnxn = pyodbc.connect('DSN=test;PWD=password')

# 打开游标

cursor =cnxn.cursor()

以上示例只是标准示例,具体的ODBC连接字符串以你自己使用的驱动为准。

查询一些数据

所有SQL语句都使用Cursor.execute()方法执行。比如select语句会返回一些结果行,你可以使用游标(Cursor)相关的函数功能(fetchone,fetchall,fetchmany)对结果进行检索。

Cursor.fetchone 用于返回一个单行( Row)对象:

cursor.execute("selectuser_id, user_name from users")

row =cursor.fetchone()

if row:

print(row)

Row 对象是类似一个python元组(tuples),不过也可以通过列名称来访问,例如:

cursor.execute("selectuser_id, user_name from users")

row =cursor.fetchone()

print('name:',row[1]) # 使用列索引号来访问数据

print('name:',row.user_name) # 或者直接使用列名来访问数据

当所有行都已被检索,则fetchone返回None.

while 1:

row = cursor.fetchone()

if not row:

break

print('id:', row.user_id)

Cursor.fetchall方法返回所有剩余行并存储于一个列表中。如果没有行,则返回一个空列表。(注意:如果有很多行,会造成大量内存占用。Fetchall会一次性将所有数据查询到本地,然后再遍历)

cursor.execute("selectuser_id, user_name from users")

rows = cursor.fetchall()

for row in rows:

print(row.user_id, row.user_name)

如果并不在意数据处理时间,可以使用光标本身作为一个迭代器,逐行迭代。这样可以节省大量的内存开销,但是由于和数据来回进行通信,速度会相对较慢:

cursor.execute("selectuser_id, user_name from users"):

for row in cursor:

print(row.user_id, row.user_name)

由于Cursor.execute总是返回游标(cursor), 所以也可以简写成:

for row incursor.execute("select user_id, user_name from users"):

print(row.user_id, row.user_name)

我们可以在execut中使用”””三重引号,来应用多行SQL字符串。这样sql的可读性大大增强。这是python特有的特性:

cursor.execute(

"""

select user_id, user_name

from users

where last_logon '2001-01-01'

and bill_overdue = 1

""")

SQL参数

ODBC支持使用问号作为SQL的查询参数占位符。可以在execute方法的SQL参数之后,提供SQL参数占位符的值:

cursor.execute(

"""

select user_id, user_name

from users

where last_logon ?

and bill_overdue = ?

""", '2001-01-01', 1)

这样做可以防止SQL注入攻击,提高安全性。如果使用不同的参数反复执行相同的SQL它效率会更高,这种情况下该SQL将只预装(prepared )一次。(pyodbc只保留最后一条编写的语句,所以如果程序在语句之间进行切换,每次都会预装,造成多次预装。)

Python的DB API指定参数应以序列(sequence)对象传递,所以pyodbc也支持这种方式:

cursor.execute(

"""

select user_id, user_name

from users

where last_logon ?

and bill_overdue = ?

""", ['2001-01-01', 1])

插入数据

插入数据使用相同的函数 - 通过传入insert SQL和相关占位参数执行插入数据:

cursor.execute("insertinto products(id, name) values ('pyodbc', 'awesome library')")

cnxn.commit()

cursor.execute("insertinto products(id, name) values (?, ?)", 'pyodbc', 'awesome library')

cnxn.commit()

注意:调用cnxn.commit()。发成错误可以回滚。具体需要看数据库特性支持情况。如果数据发生改变,最好进行commit。如果不提交,则在连接中断时,所有数据会发生回滚。

更新和删除数据

更新和删除工作以同样的方式:通过特定的SQL来执行。通常我们都想知道更新和删除的时候有多少条记录受到影响,可以使用Cursor.rowcount来获取值:

cursor.execute("deletefrom products where id ?", 'pyodbc')

print('Deleted {}inferior products'.format(cursor.rowcount))

cnxn.commit()

由于execute 总是返回游标(允许你调用链或迭代器使用),有时我们直接这样简写:

deleted =cursor.execute("delete from products where id 'pyodbc'").rowcount

cnxn.commit()

注意一定要调用commit。否则连接中断时会造成改动回滚。

技巧和窍门

引号

于单引号SQL是有效的,当值需要使用单引号时,使用用双引号包围的SQL:

cursor.execute("deletefrom products where id 'pyodbc'")

如果使用三重引号, 我们可以这样使用单引号:

cursor.execute(

"""

delete

from products

where id 'pyodbc'

""")

列名称

Microsoft SQLServer之类的一些数据库不会产生计算列的列名,在这种情况下,需要通过索引来访问列。我们也可以使用sql列别名的方式,为计算列指定引用名称:

row =cursor.execute("select count(*) as user_count fromusers").fetchone()

print('{}users'.format(row.user_count)

当然也可以直接使用列索引来访问列值:

count =cursor.execute("select count(*) from users").fetchone()[0]

print('{}users'.format(count)

注意,上例的首列不能是Null。否则fetchone方法将返回None并且会报NoneType不支持索引的错误。如果有一个默认值,经常可以是ISNULL或合并:

maxid =cursor.execute("select coalesce(max(id), 0) fromusers").fetchone()[0]

自动清理

连接(默认)在一个事务中。如果一个连接关闭前没有提交,则会进行当前事务回滚。很少需要finally或except 语句来执行人为的清理操作,程序会自动清理。

例如,如果下列执行过程中任何一条SQL语句出现异常,都将引发导致这两个游标执行失效。从而保证原子性,要么所有数据都插入发生,要么所有数据都不插入。不需要人为编写清理代码。

cnxn =pyodbc.connect(...)

cursor = cnxn.cursor()

cursor.execute("insertinto t(col) values (1)")

cursor.execute("insertinto t(col) values (2)")

cnxn.commit()

从Python调用CAPL函数问题,怎么解决

你没有说具体问题是什么,以下介绍一下capl常见问题

一、capl程序组织

1、全局变量的声明

–you declare variables that can be read or changed by any part of your CAPL program.

在程序的任何部分都可以读取和修改。

–It is a good idea to declare messages and timers in this section.

适合定义messages和timers。

2、事件处理

–Event procedures are blocks of code that are executed when an event occurs.

事件发生时执行。

–CAPL allows you to define event procedures for several different kinds of events.

可以为多个不同的事件定义事件处理

–Most of your program code will be in event procedures, since most actions are performed after an event, such as a message being received on the CAN bus.

大多数代码都写在事件处理中。

–Event procedures cannot return a value.

事件处理不能有返回值。

3、用户定义函数

–Your programs can contain procedures that can be used to complement CAPL’s built-in functions.

–These procedures can contain any legal CAPL code and are globally accessible.

–Putting frequently-used code in a procedure makes programs more efficient.

–User-defined functions can return a value of any simple type.

可以有返回值。

二、CAPL文件类型

★两种

*.CAN 包含CAPL程序(ASCII 文本格式)

*.CBF 编译.CAN文件得到(二进制文件),只能被CANslyzer或CANoe执行。

三、CAPL数据类型

char 8bit unsigned

byte 8bit unsigned

int 16bit signed

word 16bit unsigned

long 32bit signed

dword 32bit unsigned

float 64bit signed

double 64bit signed

message 一条通信消息

timer 秒级计时器

msTimer 毫秒级计时器

四、运算符

(雷同c语言,只列部分)

位操作部分:

= compound assignment(left shift)

= compound assignment(right shift)

= AND

^= XOR

|= OR

五、控制结构

1、if()

{

}

else

{

}

2、switch()

{

case :

default:

}

3、while()

{}

4、do{}while();

5、for(;;){}

6、break continue

7、this

如何让python调用C和C++代码

如何让python调用C和C++代码

安装python后,会有一个chm格式的python手册。要搞明白如何让python调用C/C++代码(也就是写python的 extension),你需要征服手册中的

Extending embedding厚厚的一章。在昨天花了一个小时看地头晕脑胀,仍然不知道如何写python的extension后,查阅了一些其他 书籍,最终在Python Programming On Win32书中找到了教程。

下面记录一下如何在visual studio 2005中,写一段C/C++的MessageBox代码,然后提供后python调用,最后的结果当然是显示一个MessageBox.

1. 首先要明白的是,所谓的python扩展(也就是你提供给python的c/c++代码,不一定是c/c++代码,可以是其他语言写的代码)是一个 dll,并且这个dll放在本机python安装目录下的DLLs目录下(譬如我机器上的路径是:F:Program FilesPython25DLLs),假如我们接下来要写的扩展module名为mb,python调用的代码为: import mb

mb.showMsg("Python's really amazing, I kindda love it!")

python怎么找到我们的mb模块呢?就是上面说的,我们要生成一个mb.dll,然后拷贝到Dlls目录下面,为了区别普通的dll和python专用扩展的dll,我们的 mb.dll修改成mb.pyd(python dll)

2. 搭建环境,我们要使用python提供的c头文件和lib库来进行扩展的开发。 在vs 2005下点击菜单 "工具"-"选项", 打开选项对话框,选择"项目和解决方案-VC++目录", 然后在右边"显示以下内容的目录"得comboBox上选择"包含文件”,添加python的include目录(我的机器上是"F:Program

FilesPython25include"),然后选择库文件,添加python的libs目录(我的机器上是"F:Program FilesPython25libs")。

既然扩展是一个dll,接下来我们要建立一个“动态链接库”工程,然后开始写代码:

#include python.h //python.h是包含python一些定义的头文件,在python的include目录下 /*

我的python版本是2.5, 因为安装python后它没提供debug下的lib库文件,因此你必须生成release版的dll,

想要生成dll版本的,你要到python官网上自己去下载python源代码,当然你可以继续生成release版本的dll,但dll中包含调试信息

*/

#pragma comment(lib, "python25.lib")

//先不管

static PyObject* mb_showMsg(PyObject* self, PyObject *args); /*

如果你的扩展是mb,那么必须实现一个initmb函数,并且从dll中导出这个函数,但我们在python中调用import mb时,python会去dll里去调用

initmb函数,这个函数告诉python我们有些什么函数,该怎么告诉python我们有一个showMsg函数呢?下面详解 */

//必须extern "C"下,这样不会在C++编译器里不会更改掉导出的函数名字,我第一次就犯了这样的错误

extern "C" __declspec(dllexport) void initmb() { /*

当调用mb.showMsg("Python's really amazing, I kindda love it!")时, 相当于你告诉python我有一个showMsg函数,我们怎么告诉python去调用我们dll里的mb_showMsg函数呢?技巧就是下面的方式, 定义一个字典数据结构,key = showMsg, value =mb_showMsg,METH_VARARGS是函数调用方式,仔细查手册吧 */

static PyMethodDef mbMethods[] = { {"showMsg", mb_showMsg, METH_VARARGS},

{NULL, NULL, NULL} /*sentinel,哨兵,用来标识结束*/ };

//告诉python我们的模块名叫mb, 模块包含的函数都在mbMethods字典里 PyObject *m = Py_InitModule("mb", mbMethods); } /*

接下来实现核心功能showMsg */

//第一个self参数我们用不着,具体查手册,第二个参数是python传给我们的参数,它是一个python的参数tuple

static PyObject* mb_showMsg(PyObject* self, PyObject *args) {

//我们的showMsg函数需要的是一个字符串参数 const char* msg = NULL; /*

调用特殊参数解码python传递给我们的参数,s是string,我们传递接收参数的变量地址,

如果你的功能函数需要两个参数,在PyArg_parseTuple后面继续添加接受参数的变量地址,

这个函数的原型是类似printf的不定参数的形式

PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...); */

if (!PyArg_ParseTuple(args, "s", msg)) return NULL;

//调用MB

int r = ::MessageBox(NULL, "hello", "Caption:Form C module", MB_ICONINFORMATION | MB_OK);

//返回值

return Py_BuildValue("i", r); }

将上面这段混杂着大量注释的代码拷贝到你的编辑器里,然后编译生成mb.dll,修改后缀成mb.pyd,然后拷贝到python的DLLs目录下,打开idle(python的交互程序),写入代码: import mb

mb.showMsg("Python's really amazing, I kindda love it!")

可以看到弹出来一个MessageBox。

python 怎么调用c语言接口

ctypes:  可直接调用c语言动态链接库。

使用步骤:

1 编译好自己的动态连接库

2 利用ctypes载入动态连接库

3 用ctype调用C函数接口时,需要将python变量类型做转换后才能作为函数参数,转换原则见下图:

4 Python若想获取ctypes调用的C函数返回值,需要先指定返回值类型。我们将在接下来的完整Sample中看到如何使用。

#Step 1:  test.c#include stdio.h

int add(int a, int b)

{

    return a + b;

}#Step 2: 编译动态链接库 ( 如何编译动态链接库在本文不详解,网上资料一大堆。)gcc -fPIC -shared test.c -o libtest.so  

#Step 3:  test.py

from ctypes import *mylib = CDLL("libtest.so")   或者   cdll.LoadLibrary("libtest.so")   add = mylib.add

add.argtypes = [c_int, c_int] # 参数类型,两个int(c_int是ctypes类型,见上表)

add.restype = c_int # 返回值类型,int (c_int 是ctypes类型,见上表)

sum = add(3, 6)

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。