python266函数,python666

如何用Python封装C语言的字符串处理函数

在C语言中,字符串处理是每天都要面对的问题。我们都知道C语言中其实并没有一种原生的字符串类型,‘字符串’在C语言里只是一种特殊的以''结尾的字符数组。因此,如何将C语言与更高层次的Python语言在‘字符串’处理这个问题上对接是一个有难度的问题。所幸有swig这种强大的工具。

为宽甸等地区用户提供了全套网页设计制作服务,及宽甸网站建设行业解决方案。主营业务为成都网站制作、网站建设、外贸网站建设、宽甸网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!

如何封装一个函数,它修改参数字符串的内容

假如有这样一个C语言的函数,

!-- lang: cpp --

void FillZero(char* pc,size_t * piLen)

{

size_t i=0;

while(i++*piLen/2 )

*pc++ = '0';

*pc = 0;

*piLen = i+1;

}

这个函数的功能是把字符串变成n个0。不过我们更关注函数的形式。这样的函数,表面上看char* pc是函数的参数,可是实际上它才是函数的返回值和执行的结果。piLen这个参数既是pc的最大长度,也是新的字符串的长度。我们直接用python封装,看看运行结果。

Type "help", "copyright", "credits" or "license" for more information.

import cchar

s='123456'

cchar.FillZero(s,6)

Traceback (most recent call last):

File "stdin", line 1, in module

TypeError: in method 'FillZero', argument 2 of type 'size_t *'

结果差强人意,不是我们想要得到的结果。函数的第二个参数为size_t* 我们很难用python来表示,而且python中也不存在既是输入,也是输出的参数。

swig有一个标准库,其中有一个cstring.i文件就是用来解决C语言字符串类型的问题。

我们在.i文件中加入这样几行

!-- lang: cpp --

%include "cstring.i"

%cstring_output_withsize(char* pc,size_t* pi)

void FillZero(char* pc, size_t* pi);

然后运行看结果

Type "help", "copyright", "credits" or "license" for more information.

import cchar

cchar.FillZero(10)

'00000\x00'

s=cchar.FillZero(10)

print s

00000

我们看函数的变化。首先在python里, FillZero变成了只有一个参数的函数。然后函数的返回值变成了一个字符串。其实cstring_output_size其实是一个宏,通过这个宏的定义改变了函数的形式,直接在Python中得到我们想要的结果。

其实类似cstring_output_size的宏还有好几个,我列举一下:

cstring_output_allocate(char *s,free($1));

第一个参数是指向字符串地址的指针,第二个参数为释放空间的方法。

大家考虑这一下这样的函数:

void foo(char* s)

{

s = (char*)malloc(10);

memcpy(s,"123456789",9);

}

s这个参数表面上看是输入,实际上是函数真正的输出。 函数中真正改变的东西是chars指向的字符串的值。而且char这个类型,

python或者其他脚本语言里应该都没有对应的类型。那么我们用cstring_output_allocate将这个函数转换成另外一个形式的python或者其他脚本语言的函数。转换后的函数其实是这样的,以python为例str

foo()。

!-- lang: cpp --

%module a

%include "cstring.i"

%{

void foo(char* s);

%}

%cstring_output_allocate(char *s, free(*$1));

void foo(char *s);

在python中的调用:

!-- lang: python --

import a

a.foo()

'123456789'

cstring_output_maxsize(char *path, int maxpath);

第一个参数也是可以改变的字符串首地址,第二个参数为字符串的最大长度。在Python中调用的时候,只有maxpath这个参数,返回字符串。

cstring_output_allocate(char *s, free($1));

第一个参数为指向字符串首地址的指针,第二个参数为释放指针的方法。这个宏主要是封装一种直接在函数内部malloc空间的函数。在Python中调用时没有参数,直接返回字符串。

cstring_output_allocate_size(char *s, int slen, free(*$1));

这个相当于前面两个函数的组合。在函数内部malloc空间,然后将字符串长度通过slen返回。其实在调用的时候非常简单,没有参数,直接返回字符串。

如何处理c++的std::string

std::string是C++标准类库STL中常见的类。在平时工作中大家肯定是没少用。在python中如何封装std::string? swig提供了标准库

例如函数:

!-- lang: cpp --

string Repeat(const string s)

{

return s+s;

}

只要在swig中加入这样几行:

!-- lang: cpp --

%include "std_string.i"

using namespace std;

string Repeat(const string s);

运行结果:

Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40)

[GCC 4.4.5] on linux2

Type "help", "copyright", "credits" or "license" for more information.

import cchar

cchar.Repeat('123')

'123123'

使用起来很方便,但需要注意的是,假如函数的参数的内容是可以被修改,就不能用这种方式封装。

例如:

!-- lang: cpp --

void repeat(string s)

{

s+=s;

}

这样的函数直接使用 'std_string.i' 就是无效的。遇到这种函数,只能用C语言封装成 void repeat(chars, int maxsize), 再用swig调用 'cstring_output_withsize' 这个宏再封装一次了。

IS是啥模块+ST是啥模块+AL是啥模块?

1 导入模块

1.1 问题

本案例要求先编写一个star模块,主要要求如下:

建立工作目录 ~/bin/

创建模块文件 ~/bin/star.py

模块中创建pstar函数,实现打印50个星号的功能

然后练习导入模块,调用模块中的函数:

在交互解释器中导入模块

调用模块的函数

1.2 方案

使用vim当作文本编辑器编写python脚本,使用RHEL6系统中自带的python解释器加载模块。

注意,模块及函数在后续课程中有详细介绍,这里只是因为经常要用到导入模块,所以需要大致了解一下。

模块支持从逻辑上组织python代码。当代码量变得相当大的时候,最好把代码分成一些有组织的代码段,前提是保证它们的彼此交互。

这些代码段是共享的,所以python允许调入一个模块,允许使用其他模块的属性来利用之前的工作成果,实现代码重用。这个把其他模块中属性附加到你的模块中的操作叫做导入(import)。

给定一个模块名之后,只可能有一个模块被导入到python解释器中,所以在不同模块间不会出现名称交叉现象;每个模块都定义了它自己的唯一的名称空间,访问一个模块的属性可以使用句点表示法,比访问star模块中的pstar函数的写法为:star.pstar()。

1.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建目录结构

Linux在执行命令时,它会到PATH环境变量定义的路径中去查找,如果查到则执行,如果查不到则提示命令找不到。

为了使得编写的脚本在任意位置可以直接执行,并支持按TAB键补齐,最好将命令放到PATH环境变量定义的路径中。

在Linux系统中,每个用户的家目录下的bin目录,默认在PATH环境变量中,但是系统默认并没有创建该目录。

[root@py01 ~]# echo \$PATH

/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/root/bin

2)根据PATH变量内容创建bin目录

[root@py01 ~]# mkdir /root/bin

步骤二:创建模块文件

1)创建模块文件

python的模块名就是脚本文件名去掉.py的扩展名,所以star模块的文件名就是star.py。

在创建文件时,不要使用python已有的模块名。因为在import模块时,如果自己创建的模块文件和python自带的模块重名,那么,用户自己创建的模块将被导入,用户也就无法使用python自身的模块了。

判断python是否拥有某个模块,最简单的办法就是,进入到python交互解释器中,然后执行import命令,如果提示ImportError则表示python默认没有该模块。

[root@py01 ~]# cd bin

[root@py01 ~]# vim star.py

2)编写pstar函数

像shell本一样,python脚本文件的第一行也是解释器。

在python中,使用def定义函数,def后面紧跟函数名,函数名后面是一对圆括号,圆括号包含可选的参数。

需要注意的是,()并不是函数名的一部分,另外最后不要丢掉冒号。在python中,如果一个关键字后面有子语句块,那么该关键字的行尾都需要加冒号。

函数体部分(代码组)必须缩进,一般缩进4个空格,而且所有的子语句必须缩进相同的空白。

函数定义只是说有这样的功能,并不执行。所以该程序文件如果直接以脚本的方式执行,那么它不会产生任何输出。

#!/usr/bin/env python

def pstar():

print '*' * 50

步骤三:导入模块并测试

在这里需要注意的是,需要在模块文件所在的目录下打开交互解释器。因为python在导入模块时会在固定的几个位置去搜索模块,如果找到则导入,否则将出错。当前的工作目录也是python在搜索模块时会查找的路径。

[root@py01 bin]# python

Python 2.6.6 (r266:84292, Oct 12 2012, 14:23:48)

[GCC 4.4.6 20120305 (Red Hat 4.4.6-4)] on linux2

Type "help", "copyright", "credits" or "license" for more information.

import star

解释器需要知识执行的是哪个模块中的函数,所以写法应该是:“模块.函数”。

注意,函数名后面的圆括号不要丢掉,python调用函数使用圆括号,表示执行该函数的意思。如果没有圆括号,只是引用,不调用,也就是不会执行该函数。

star.pstar()

**************************************************

文章链接:

Python之OpenGL笔记(22):箭头控制平面直角坐标系中的圆圈移动

1、箭头控制平面直角坐标系中的圆圈上下左右移动;

glfw.set_key_callback(window, on_key) 设置键盘回调函数。

def on_key(window, key, scancode, action, mods):打开键(窗体、键值、扫描码、动作、辅助键)

   参数说明:

   window :发生事件的窗体

   key :激发的键值

   scancode :键值的系统扫描码

   action:动作GLFW_PRESS, GLFW_RELEASE or GLFW_REPEAT.

   mods: 辅助键ALT,CTRL,SHIFT,META

KEY_0 = 48

KEY_1 = 49

KEY_2 = 50

KEY_3 = 51

KEY_4 = 52

KEY_5 = 53

KEY_6 = 54

KEY_7 = 55

KEY_8 = 56

KEY_9 = 57

KEY_A = 65

KEY_APOSTROPHE = 39

KEY_B = 66

KEY_BACKSLASH = 92

KEY_BACKSPACE = 259

KEY_C = 67

KEY_CAPS_LOCK = 280

KEY_COMMA = 44

KEY_D = 68

KEY_DELETE = 261

KEY_DOWN = 264

KEY_E = 69

KEY_END = 269

KEY_ENTER = 257

KEY_EQUAL = 61

KEY_ESCAPE = 256

KEY_F = 70

KEY_F1 = 290

KEY_F10 = 299

KEY_F11 = 300

KEY_F12 = 301

KEY_F13 = 302

KEY_F14 = 303

KEY_F15 = 304

KEY_F16 = 305

KEY_F17 = 306

KEY_F18 = 307

KEY_F19 = 308

KEY_F2 = 291

KEY_F20 = 309

KEY_F21 = 310

KEY_F22 = 311

KEY_F23 = 312

KEY_F24 = 313

KEY_F25 = 314

KEY_F3 = 292

KEY_F4 = 293

KEY_F5 = 294

KEY_F6 = 295

KEY_F7 = 296

KEY_F8 = 297

KEY_F9 = 298

KEY_G = 71

KEY_GRAVE_ACCENT = 96

KEY_H = 72

KEY_HOME = 268

KEY_I = 73

KEY_INSERT = 260

KEY_J = 74

KEY_K = 75

KEY_KP_0 = 320

KEY_KP_1 = 321

KEY_KP_2 = 322

KEY_KP_3 = 323

KEY_KP_4 = 324

KEY_KP_5 = 325

KEY_KP_6 = 326

KEY_KP_7 = 327

KEY_KP_8 = 328

KEY_KP_9 = 329

KEY_KP_ADD = 334

KEY_KP_DECIMAL = 330

KEY_KP_DIVIDE = 331

KEY_KP_ENTER = 335

KEY_KP_EQUAL = 336

KEY_KP_MULTIPLY = 332

KEY_KP_SUBTRACT = 333

KEY_L = 76

KEY_LAST = 348

KEY_LEFT = 263

KEY_LEFT_ALT = 342

KEY_LEFT_BRACKET = 91

KEY_LEFT_CONTROL = 341

KEY_LEFT_SHIFT = 340

KEY_LEFT_SUPER = 343

KEY_M = 77

KEY_MENU = 348

KEY_MINUS = 45

KEY_N = 78

KEY_NUM_LOCK = 282

KEY_O = 79

KEY_P = 80

KEY_PAGE_DOWN = 267

KEY_PAGE_UP = 266

KEY_PAUSE = 284

KEY_PERIOD = 46

KEY_PRINT_SCREEN = 283

KEY_Q = 81

KEY_R = 82

KEY_RIGHT = 262

KEY_RIGHT_ALT = 346

KEY_RIGHT_BRACKET = 93

KEY_RIGHT_CONTROL = 345

KEY_RIGHT_SHIFT = 344

KEY_RIGHT_SUPER = 347

KEY_S = 83

KEY_SCROLL_LOCK = 281

KEY_SEMICOLON = 59

KEY_SLASH = 47

KEY_SPACE = 32

KEY_T = 84

KEY_TAB = 258

KEY_U = 85

KEY_UNKNOWN = -1

KEY_UP = 265

KEY_V = 86

KEY_W = 87

KEY_WORLD_1 = 161

KEY_WORLD_2 = 162

KEY_X = 88

KEY_Y = 89

KEY_Z = 90


网页题目:python266函数,python666
分享网址:http://myzitong.com/article/hdepeg.html