显示标签为“python”的博文。显示所有博文
显示标签为“python”的博文。显示所有博文

2009/12/15

PyGTK下编写多线程程序

没有评论:
虽然在PyGTK中Python有关多线程的库(thread,threading)可以使用,但其行为常现异常,所以一定要按照PyGTK的要求编写多线程应用程序。

How threads works in pygtk using the threading module?

Threads are a way for a program to split itself into two or more simultaneously running tasks. The way that we create threads in python is writing subclasses of the threading.Thread class, the method run, should be overloaded so we include there the code that we want to be rant on each thread.

In order to create a new thread, we should create a new Thread object and then, call the start method which creates the new thread, and executes the run method in its context.

The problem with PyGTK is that the gtk.main() loop won't refresh the screen each time that the fraction is set, we need to use the gtk thread engine. We need to call the gtk.thread_init() function to start the thread engine, this call should be made on the same thread that the gtk.main() function is called. In fact, calling it right afer importing the gtk module is a good practice.

Thus, we should use gtk.threads_enter() before any access to gtk object, and, once we end up doing transformations, we should call gtk.threads_leave().

We should call to the stop method in the exit callback so when the window is closed the application ends the thread and the script doesn't hangs.

只允許主線程修改圖形界面

這是較常用的一種方式,但編寫時略顯複雜。首先,在程序初始化時調用(一定在gtk.main()之前運行):
gobject.threads_init()
多線程的實現方式與純Python相同:
t=threading.Thread(target=新线程的函数)
t.start()
要修改界面的代碼則使用gobject.idle_add加到GTK的主循環中。
gobject.idle_add(新线程函数, 参数)
注意如果新線程函數返回True,則該函數仍在GTK的主循環中,如果返回False,則退出主循環。下面的例子是PyGTK.org上給出的:
import threading
import time
import gobject
import gtk

gobject.threads_init()

class MyThread(threading.Thread):
 def __init__(self, label):
     super(MyThread, self).__init__()
     self.label = label
     self.quit = False

 def update_label(self, counter):
     self.label.set_text("Counter: %i" % counter)
     return False

 def run(self):
     counter = 0
     while not self.quit:
         counter += 1
         gobject.idle_add(self.update_label, counter)
         time.sleep(0.1)

w = gtk.Window()
l = gtk.Label()
w.add(l)
w.show_all()
w.connect("destroy", lambda _: gtk.main_quit())
t = MyThread(l)
t.start()

gtk.main()
t.quit = True

允許所有線程修改圖形界面

這種方法要簡單很多。與前面類似,在程序初始化時調用:
gtk.gdk.threads_init()
不過要把gtk.main()用下面兩個函數括起來:
gtk.threads_enter()
gtk.main()
gtk.threads_leave()
其它線程也是如此,在修改界面內容的代碼前後加上
gtk.threads_enter()
...
gtk.threads_leave()

The following example shows how to do it using a random fraction for the progress bar:

import threading
import random, time
import gtk
#Initializing the gtk's thread engine
gtk.threads_init()


class FractionSetter(threading.Thread):
 """This class sets the fraction of the progressbar"""

#Thread event, stops the thread if it is set.
stopthread = threading.Event()

def run(self):
  """Run method, this is the code that runs while thread is alive."""

 #Importing the progressbar widget from the global scope
 global progressbar

 #While the stopthread event isn't setted, the thread keeps going on
 while not self.stopthread.isSet() :
  # Acquiring the gtk global mutex
  gtk.threads_enter()
  #Setting a random value for the fraction
  progressbar.set_fraction(random.random())
  # Releasing the gtk global mutex
  gtk.threads_leave()
 
  #Delaying 100ms until the next iteration
  time.sleep(0.1)
 
def stop(self):
  """Stop method, sets the event to terminate the thread's main loop"""
 self.stopthread.set()

def main_quit(obj):
 """main_quit function, it stops the thread and the gtk's main loop"""
#Importing the fs object from the global scope
global fs
#Stopping the thread and the gtk's main loop
fs.stop()
gtk.main_quit()

#Gui bootstrap: window and progressbar
window = gtk.Window()
progressbar = gtk.ProgressBar()
window.add(progressbar)
window.show_all()
#Connecting the 'destroy' event to the main_quit function
window.connect('destroy', main_quit)

#Creating and starting the thread
fs = FractionSetter()
fs.start()

gtk.main()

Refer to:
http://aruiz.typepad.com/siliconisland/2006/04/threads_on_pygt.html
http://docs.python.org/library/threading.html

2009/07/12

python: handle exceptions

没有评论:
try:
# code here
except Exception, err:
sys.stderr.write('ERROR: %s\n' % str(err))
import traceback
traceback.print_exc()
else:
# normal
finally:
###


Refer:
Python Exception Handling Techniques

traceback — Print or retrieve a stack traceback

2009/06/29

Pyrex- 连接Python与C的桥梁

没有评论:
使用Pyrex将从Pyrex代码生成一个C源文件,编译该C源文件即可生成Python的扩展模块。从而使编写Python的C扩展更加容易。Pyrex在 Python 中添加了类型声明,使得Python与C数据类型相互转换变得容易。
ubuntu 下安装: sudo apt-get install pyrex

windows 下安装: 从其官方网站http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex下载Pyrex的ZIP文件。将其解压后,进入其目录,运行如下所示命令将安装Pyrex。
python setup.py install
它将 pyrexc.py放在 c:\python25\Scripts\目录下。


首先编写如下所示“test.pyx”文件。
def test(): return 'A test file!'

windows下转换test.pyx成C, 运行如下所示的命令:
c:\python25\python.exe c:\python25\Scripts\pyrexc.py test.pyx
运行完命令后将在目录中生成“test.c”.

在VC++ 中将“test.c”编译或链接。


Pyrex文件语法

Pyrex文件完全使用了Python的语法。在编写Pyrex文件时,只需按照Python的语法编写即可。在Pyrex中可以定义C语言中的结构体、枚举等类型,也可以使用C语言中的数据类型。

1.数据类型

Pyrex定义了与C语言中相对应的数据类型,使用“cdef”可以在Pyrex中使用C语言中的数据类型。代码如下所示。
cdef char *s # 相当于C中的字符串
cdef int x,y # 相当于C中的int型
cdef int z[4] # 相当于C中的数组
cdef float f # 相当于C中的浮点型
cdef int *p # 相当于C中的指针

2.结构体、联合及枚举

除了定义C中的数据类型以外,还可以使用“cdef”定义C中的结构体、联合、枚举等。代码如下所示。
cdef struct Human: # 定义结构体
char *name
char *sex
int age
cdef union Fruit: # 定义联合体
char *apple
char *banana
char *orange
cdef enum: #定义枚举
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday

3.函数

使用“cdef”可以像使用Python中的 “def”一样来定义一个函数。在Pyrex文件中既可以使用“def”来定义函数,也可以使用“cdef”来定义函数。不同的是,使用“def”定义的 函数,只能使用Python的数据类型,而使用“cdef”定义的函数则可以使用C中的数据类型。另外,使用“def”定义的函数可以被模块导出,在 Python中使用。而使用“cdef”定义的函数则不能被Python使用。代码如下所示。
cdef int sum(int x, int y): # 使用C数据类型定义函数
return x + y
cdef sum(x, y): # 如果没有声明参数类型,则表示为Python中的类型
return x + y
cdef object sum(object x, object y): # 使用object显式地表示参数为Python中的类型
return x + y

4.使用类

使用“cdef”也可以在Pyrex文件中定义类。需要注意的是如果通过继承创建类,则父类应该在该Pyrex文件中定义,否则应该使用“extern”表示父类在外部定义。代码如下所示。
cdef class Stud: # 使用cdef定义类
def setname(self,n): # 定义setname方法
self.name = n
def showname(self): # 定义showname方法
print self.name
cdef class Student(Stud): # 通过继承创建类
def setnum(self,n): # 定义setnum方法
self.num = n
def shownum(self): # 定义shownum方法
print self.num

5.使用include和外部C函数

Pyrex支持类似于C语言头文件的“.pxi”文 件。使用“.pxi”可以将较大的Pyrex文件分成多个文件,这样便于维护。“.pxi”文件像C语言中的头文件一样,只要使用“include”包含 就可以了。除此以外,在Pyrex中也可以使用C语言头文件中声明的函数原型。例如使用Python/C API中的 PyRun_SimpleString函数,则可以使用如下写法。
cdef extern from "Python.h":
int PyRun_SimpleString(char *command)

python使用pyrex编译成可执行文件

没有评论:
使用pyrex,python完全可以用来开发商业软件,而不用担心源代码泄露。
在http: //www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/下载。本来Pyrex是一个用来混合 编写python和c程序的东西,然后转换为c代码,再编译成可执行文件。于是这里就相当于提供了一种方法可以将python代码转换为c代码,这样就可 以把python程序编译为真正的可执行文件了。

而py2exe只是一个对python程序打包的工具。它可以让这个程序脱离python环境来执行,但并不能保护源代码,因为源 代码其实也包含在其中。

步骤:
1。使用obfuscator 混淆 python 代码;
2。使用 pyrex转换成C代码;
3。编译成exe或者dll库。


假设我们有一个简单的python程序,文件名为 go.py
def add(a, b):
print a+b # 为了方便看到函数调用,输出一下
retur a+b
仅仅做一个简单的加法操作。那我们想把它编译为可执行文件的话,需要进行以下几步:
1.修改go.py文件,在里面添加一个c函数,当然要用Pyrex的语法,用这个函数来调用python程序的入口函数(在这里就是add了)。修改go.py为go.pyx。
在这里就是添加一个:
cdef public int c_add(int a, int b):
return add(a, b)
2.添加一个头文件 go.pxi,让主函数能找到go.py里的c函数的申明
cdef extern int (c_add(int, int))

3.编写一个主函数文件main.c,在该主函数中包含go.h(这个文件会自动生成), 并调用前面设计的c函数。
#include
#include
#include
#include "go.h"

int main(int argc, char *argv[])
{
Py_Initialize();

initgo(); // 这个地方的函数名字为init加上模块名,就是原来那个py文件的名字
c_add(2, 5);

Py_Finalize();
return 0;
}
好了,现在编译就是:
pyrexc go.pyx
gcc go.c main.c -I/usr/include/python2.5 -L/usr/lib/ -lpython2.5 -o go
就生成了叫go的可执行文件,执行它,就得到了想要的结果!

注:此方法在linux上通过。

2009/06/20

python的调试

没有评论:
一般直接看stderr 输出, 或者打印到stdout。如某些情况无法在terminal看到输出( 如python非主程序,被C调用 ),可以重定向到文件:

# in python script
stdout = open("file.log", "w")
stderr = stdout

print "debug thing..."

然后到文件中查看。

更进一步,如果需要单步跟踪,可以使用 pdb 调试。 其在windows下为 wxpython + winpdb

2009/05/06

Python 中循环引用导致内存泄漏

没有评论:
python的垃圾收集功能。首先python中的所有对象都是继承object对象,python源码中关于object类型的定义:
[object.h]
typedef struct _object{
int ob_refcnt;
struct _typeobject * ob_type;
} PyObject;
其中ob_type是用来确定对象类型的变量,而ob_refcnt是用于垃圾收集的对象的引用计数。当对象创建的时候此成员的值就是1,例如 a=MyType(),a的引用计数就是1,如果进行对象赋值操作,例如b = a, a的引用计数就变成2。相对的,如果再运行b = c,那么a的引用计数就减1. 当对象的引用计数为0时,表明没有其他对象引用该对象。该对象所分配的内存就可以回收了

当一个对象的引用计数减少至零时,它就会在适当时机被垃圾回收车拉走。然而,特定情况(循环引用)会阻止垃圾回收车销毁不再使用的对象,看下面的例子:

1 a = { } # a 的引用为 1
2 b = { } # b 的引用为 1
3 a['b'] = b # b 的引用增 1,b的引用为2
4 b['a'] = a # a 的引用增 1,a的引用为 2
5 del a # a 的引用减 1,a的引用为 1
6 del b # b 的引用减 1, b的引用为 1

在这个例子中,del语句减少了 a 和 b 的引用计数并删除了用于引用的变量名,可是由于两个对象各包含一个对方对象的引用,虽然最后两个对象都无法通过名字访问了,但引用计数并没有减少到零。因此这个对象不会被销毁,它会一直驻留在内存中,这就造成了内存泄漏。

解决办法1: break the circle.
before 5: a['b'] = None

因此,有 __del__() 函数的对象(如list,dict)间的循环引用是导致内存泄漏的主凶。特别说明:对没有 __del__() 函数的 Python 对象(如int)间的循环引用,是可以被自动垃圾回收掉的。

慎写自己的__del__() 函数啊 :-(

解决办法2:
定期的运行 pythn gc module的搜索器,若发现一个对象已经无法被访问 (untouchable),不论该对象引用计数是否为 0 ,都主动销毁它 del gc.garbage[:]。通过 gc 模块的函数来进行调整和控制gc.enable()。

print 'begin collect...'
_unreachable = gc.collect()
print 'unreachable object num:%d' % _unreachable
print 'garbage object num:%d' % len(gc.garbage)
del gc.garbage[:]

解决办法3: (调试)
# 通过引用计数判断数据单元是否可以回收
# 通过扩展模块gc中的接口可以分析调试垃圾回收的情况

使用get_objects( )方法可以取得当前所有不能回收的对象(引用计数不为0)的列表
可以写个循环把他们都打印出来调试。该方法只执行一次,因为 它本生会增加变量的引用,特别是在有内存泄露的情况下.
For example:

# after potential wrong code
objs = gc.get_objects()
for obj in objs:
if isinstance( obj, XXX): print obj # check objects here





References:
[1] Python的Garbage Collector module (import gc)
http://docs.python.org/library/gc.html

[2] http://blog.csdn.net/horin153/archive/2007/06/08/1644512.aspx

Python和C混合编程时需注意内存泄漏

没有评论:
看下面的例子:

PyObject* py_func(PyObject *self, PyObject *args)
{
PyObject *pStr = Py_BuildValue("s", "a string for test....");
PyObject *pList = PyList_New(1);
PyList_SetItem(pList, 0, pStr);
Py_DECREF(pStr); // decrease the reference of pStr.
return pList;
}

当pStr被创建时,引用计数增1,加入pList后,引用计数又增1;同样,pList被创建时,引用计数也增1;pList返回给Python 使用,当不再需要时,pList和其包含的每个元素的引用计数都将减1;如果我们不在pStr加入pList后对其引用计数减1,每个创建的pStr都不会被销毁,一直保存在内存中。

另: 以下方式只对 PyList_SetItem(), PyTuple_SetItem()有效,其他的则会产生内存泄露

PyFunctions_XXXX(pList, 0, Py_BuildValue("s", "never destroy..."));

python文档告诉我们这两个函数是 burrow reference.

2009/05/05

C扩展接口程序中的Python引用计数器泄漏

没有评论:
如果是python code产生的内存泄露,可以用gc module来调试;

如果是接口C程序产生的内存泄露,可以用工具linux ,valgrind 或 vc++ 并 visual leak detector来调试。个人感觉后者更简单易用。

valgrind 为linux 下free 内存调试软件

http://valgrind.org/

内存泄漏调试过程
* 使用分析工具Valgrind对整个应用程序的运行过程进行分析
* 运行命令行
valgrind -v --leak-check=yes --num-callers=256 --logfile=d python d.py

分析内存占用情况
* 为valgrind增加命令行参数--show-reachable=yes,这将会把还在使用的内存情况也打印出来
* 运行命令行
valgrind -v --show-reachable=yes --leak-check=yes --num-callers=256 \
--logfile=d python d.py


附: 引用计数相关函数
(1)void Py_INCREF(PyObject *o)
void Py_XINCREF(PyObject *o)
增加引用计数,如果不确定对象o是否为空,使用后者

(2)void Py_DECREF(PyObject *o)
void Py_XDECREF(PyObject *o)
减少引用计数,如果不确定对象o是否为空,使用后者

(3)void Py_CLEAR(PyObject *o)同上

2.4以后版本使用Py_IncRef(PyObject *o), Py_DecRef(PyObject *o), Py_CLEAR(PyObject *o)

2009/05/01

Install CGAL-python under Ubuntu 9.04

没有评论:
如何安装:

问题在于ubuntu 9.04 uses python 2.6 instead of python 2.5, which makes the previous build of cgal-python0.9.3 invalid. Need to rebuild cgal-python.

Since the newest CGAL version is 3.4, we upgrade it from 3.3.

--------------------------
install boost-python

still use libboost-python1.34.1. note that 1.37.0 does not make the cgal-python building correct. If 1.37.0 exists, remove from synatic.

sudo apt-get install libboost-python1.34.1
sudo apt-get install libboost-python-dev

-------------------------
install CGAL 3.4

1. download
http://gforge.inria.fr/frs/?group_id=52

2. sudo apt-get install cmake

3. follow the instruction of INSTALL under CGAL-3.4 directory
cmake .

4. make

5. sudo make install

------------------------

install cgal-python0.9.4 beta1 (the latest. I guess 0.9.3 is also OK.)


download the package, and do
export CPATH=/usr/include/python2.6:$CPATH
export LIBRARY_PATH=/usr/local/lib:$LIBRARY_PATH

python setup.py build
python setup.py install (possibly as root)

2009/03/31

how to get python25_d.lib and python25_d.dll

没有评论:
If do want to use "python25_d.lib" and/or "python25_d.dll" to debug python scripts,
can use Visual C++ to compile python25 source code.

1. download python-2.5.4.tgz (11M) from python's official website:
http://www.python.org/ftp/python/2.5.4/Python-2.5.4.tgz

2. Unzipped and look for directory "python-2.5.4\PCbuild8\"
(Note that: directory ".\PCbuild\" is for VC 7.0)

Use VC++ 2005 (ver8.0) to open the pcbuild.sln under directory ".\PCbuild8\". You will see 20 projects. Build only two projects "python" and "pythoncore".


3. There will be two files "python25_d.lib" and "python25_d.dll" generated under directory ".\PCbuild8\win32debug". Copy them into "c:\python25\libs" and "c:\windows\system32"
respectively. Previously, "python25.dll" and "python25.lib" already there.


4. Turn on "debug" in VC and rebuild. Succeed.

However, I did not figure out how to use debug version in VC to debug into my python file.:-(

Note: Python's latest version is 2.6. But since I use "pylab/matplotlib" which currently only offers package ver0.98 for python2.5 under windows. So,... python2.5.4 is my choice.

2009/03/29

C++和python的相互调用-II

没有评论:
编写扩展 Use python to write extension for C++ program

Visual C++ 2005 下创建新 Win32/ Win32 DLL project. 这样不用手写 *.def文件和手工编译链接。
然后将附带cpp文件做成 dll.

Python can only use this "*.dll" by changing it to "*.pyd".

Example:
1. Change the built "pyUtil.dll" to file name "pyUtil.pyd".
2. In python command line:
import sys
sys.path.append(".\\") # where pyUtil.pyd locates
# Or, put pyUtil.pyd file under python dll directory, "C:\Python25\DLLs".
# Note: "C:\Python25\libs" store static library like "pyUtil.lib".
import pyUtil
pyUtil.Recognise("ddddd")


C program can use python extension like static library.
That is: C program with pyUtil.py under the same directory,
which needs support of "C:\python25\libs\python25.lib".

C program can use this "*.dll" normally.
The usage is same as above.
Note that put pyUtil.dll under directory "c:\windows\system32\".



Source code for dll:
//////////////////////////////////////////////////////////////////
// pyUtil.cpp :


#ifdef _MANAGED
#pragma managed(push, off)
#endif


#include "stdafx.h"
#include "string.h"
#include "Python.h" // added

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
/*
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
*/
return TRUE;
}


/////////// my code
std::string Recognise_Img(const std::string url)
{ return "hello, " +url;
}

static PyObject* Recognise(PyObject *self, PyObject *args)
{
const char *url;
std::string sts;

if (!PyArg_ParseTuple(args, "s", &url)) // parse python objects from input
return NULL;

sts = Recognise_Img(url); // add your code here.

return Py_BuildValue("s", sts.c_str() ); // return python objects if used in python
}


static PyMethodDef AllMyMethods[] = { // declare of function list
{"Recognise", Recognise, METH_VARARGS}, // function name
{NULL, NULL} // need this to end decl
};

extern "C" PyMODINIT_FUNC initpyUtil() // initMyPythonModuleName
{
PyObject *m, *d;
m = Py_InitModule("pyUtil", AllMyMethods); // Module Name = file name
d = PyModule_GetDict(m);
}



#ifdef _MANAGED
#pragma managed(pop)
#endif

2009/03/23

C++扩展和嵌入Python

没有评论:

C++扩展和嵌入Python
作者:胡金山 来源:www.vckbase.com

Paper source

下载源代码

Python简介

Python是一种简单易学,功能强大的解释型编程语言,它有简洁明了的语法,高效率的高层数据结构,能够简单而有效地实现面向对象编程,特别适用于快速应用程序开发,也可以用来开发大规模的重要的商业应用。Python是一个理想的脚本语言。
Python免费开源,可移植到多种操作系统,只要避免使用依赖于特定操作系统的特性,Python程序无需修改就可以在各种平台上面运行。
Python拥有现代编程语言所具有的一切强大功能,Python标准库十分庞大,可以帮助开发者处理各种工作,如:图形用户界面、文件处理、多媒体、正 则表达式、文档生成、单元测试、线程、数据库、网络通讯、网页浏览器、CGI、FTP、电子邮件、XML、HTML、WAV文件、密码系统、Tk和其他与 系统有关的操作。只要安装了Python,这些功能都是可用的除了标准库以外,还有许多其他高质量的库,如wxPython、Twisted和 Python图形库等等数不胜数。
Python容易扩展和嵌入。Python提供的许多标准模块支持C或者C++接口。Python和C可以一起工作,它可以嵌入到C或者C++的应用程序 当中,因此可用Python语言为应用程序提供脚本接口,由于支持跨语言开发,可用Python设计概念化应用程序,并逐步移植到C,使用前不必用C 重写应用程序。(Jython使Python可以和Java一起工作,使开发者可以在Python里面调Java的包,也可以在Java里面使用 Python的对象。还有更妙的,由于Jython的解释器完全用Java编写,因此可以在支持Java的任何平台上部署Python程序,甚至WEB浏 览器也可以直接运行Python脚本。)

提出问题

在某个C++应用程序中,我们用一组插件来实现一些具有统一接口的功能,我们使用Python来代替动态链接库形式的插件,这样可以方便地根据需求的变化 改写脚本代码,而不是必须重新编译链接二进制的动态链接库。Python强大的功能足以胜任,但是有一些操作系统特定的功能需要用C++来实现,再由 Python调用。所以,最基础地,我们需要做到:
  1. 把Python嵌入到C++应用程序中,在C++程序中调用Python函数和获得变量的值;
  2. 用C++为Python编写扩展模块(动态链接库),在Python程序中调用C++开发的扩展功能函数。

常用的Python/C API介绍

下面是例子中用到的几个Python/C API的简要介绍及示例代码。注意,这并不是这些函数的详细介绍,而仅仅是我们所用到的功能简介,更详细内容请参考文档[1]、[2]、[3]、[4]。
打开Microsoft Visual Studio .NET 2003,新建一个控制台程序
  1. #include

并在main函数里加入示例代码。
  1. //先定义一些变量
  2. char *cstr;
  3. PyObject *pstr, *pmod, *pdict;
  4. PyObject *pfunc, *pargs;

1. void Py_Initialize( )

初始化Python解释器,在C++程序中使用其它Python/C API之前,必须调用此函数,如果调用失败,将产生一个致命的错误。例:
  1. Py_Initialize();

2. int PyRun_SimpleString( const char *command)

执行一段Python代码,就好象是在__main__ 函数里面执行一样。例:
  1. PyRun_SimpleString("from time import time,ctime "
  2. "print ''Today is'',ctime(time()) ");

3. PyObject* PyImport_ImportModule( char *name)

导入一个Python模块,参数name可以是*.py文件的文件名。相当于Python内建函数__import__()。例:
  1. pmod = PyImport_ImportModule("mymod"); //mymod.py

4. PyObject* PyModule_GetDict( PyObject *module)

相当于Python模块对象的__dict__ 属性,得到模块名称空间下的字典对象。例:
  1. pdict = PyModule_GetDict(pmod);

5. PyObject* PyRun_String( const char *str, int start, PyObject *globals, PyObject *locals)

执行一段Python代码。
  1. pstr = PyRun_String("message", Py_eval_input, pdict, pdict);

6. int PyArg_Parse( PyObject *args, char *format, ...)

解构Python数据为C的类型,这样C程序中才可以使用Python里的数据。例:
  1. /* convert to C and print it*/
  2. PyArg_Parse(pstr, "s", &cstr);
  3. printf("%s ", cstr);

7. PyObject* PyObject_GetAttrString( PyObject *o, char *attr_name)

返回模块对象o中的attr_name 属性或函数,相当于Python中表达式语句:o.attr_name。例:
  1. /* to call mymod.transform(mymod.message) */
  2. pfunc = PyObject_GetAttrString(pmod, "transform");

8. PyObject* Py_BuildValue( char *format, ...)

构建一个参数列表,把C类型转换为Python对象,使Python可以使用C类型数据,例:
  1. cstr="this is hjs''s test, to uppercase";
  2. pargs = Py_BuildValue("(s)", cstr);

9. PyEval_CallObject(PyObject* pfunc, PyObject* pargs)

此函数有两个参数,都指向Python对象指针,pfunc是要调用的Python 函数,通常可用PyObject_GetAttrString()获得;pargs是函数的参数列表,通常可用Py_BuildValue()构建。例:
  1. pstr = PyEval_CallObject(pfunc, pargs);
  2. PyArg_Parse(pstr, "s", &cstr);
  3. printf("%s ", cstr);

10. void Py_Finalize( )

关闭Python解释器,释放解释器所占用的资源。例:
  1. Py_Finalize();


Python2.4环境没有提供调试版本的Python24d.lib,所以上述示例在release模式下编译。编译完成后,把可行文件和附2给出的 mymod.py文件放在一起,再点击即可运行。为了简化编程,附3 给出了simplepy.h。这样,调用mymod.transform变成如下形式:
  1. //#include”simplepy.h”
  2. CSimplepy py;
  3. py.ImportModule("mymod");
  4. std::string str=py.CallObject("transform",
  5. "this is hjs''s test, to uppercase");
  6. printf("%s ", str.c_str());


接下来,我们来用C++为Python编写扩展模块(动态链接库),并在Python程序中调用C++开发的扩展功能函数。生成一个取名为pyUtil的Win32 DLL工程,除了pyUtil.cpp文件以外,从工程中移除所有其它文件,并填入如下的代码:
  1. // pyUtil.cpp
  2. #ifdef PYUTIL_EXPORTS
  3. #define PYUTIL_API __declspec(dllexport)
  4. #else
  5. #define PYUTIL_API __declspec(dllimport)
  6. #endif
  7. #include
  8. #include
  9. #include
  10. BOOL APIENTRY DllMain( HANDLE hModule,
  11. DWORD ul_reason_for_call,
  12. LPVOID lpReserved
  13. ?)
  14. {
  15. switch (ul_reason_for_call)
  16. {
  17. case DLL_PROCESS_ATTACH:
  18. case DLL_THREAD_ATTACH:
  19. case DLL_THREAD_DETACH:
  20. case DLL_PROCESS_DETACH:
  21. break;
  22. }
  23. return TRUE;
  24. }
  25. std::string Recognise_Img(const std::string url)
  26. {
  27. //返回结果
  28. return "从dll中返回的数据... : " +url;
  29. }
  30. static PyObject* Recognise(PyObject *self, PyObject *args)
  31. {
  32. const char *url;
  33. std::string sts;
  34. if (!PyArg_ParseTuple(args, "s", &url))
  35. return NULL;
  36. sts = Recognise_Img(url);
  37. return Py_BuildValue("s", sts.c_str() );
  38. }
  39. static PyMethodDef AllMyMethods[] = {
  40. {"Recognise", Recognise, METH_VARARGS},//暴露给Python的函数
  41. {NULL, NULL} /* Sentinel */
  42. };
  43. extern "C" PYUTIL_API void initpyUtil()
  44. {
  45. PyObject *m, *d;
  46. m = Py_InitModule("pyUtil", AllMyMethods); //初始化本模块,并暴露函数
  47. d = PyModule_GetDict(m);
  48. }


在Python代码中调用这个动态链接库:
  1. import pyUtil
  2. result = pyUtil.Recognise("input url of specific data")
  3. print "the result is: "+ result

用C++为Python写扩展时,如果您愿意使用Boost.Python库的话,开发过程会变得更开心J,要编写一个与上述pyUtil同样功能的动态 链接库,只需把文件内容替换为下面的代码。当然,编译需要boost_python.lib支持,运行需要boost_python.dll支持。
  1. #include
  2. #include
  3. using namespace boost::python;
  4. #pragma comment(lib, "boost_python.lib")
  5. std::string strtmp;
  6. char const* Recognise(const char* url)
  7. {
  8. strtmp ="从dll中返回的数据... : ";
  9. strtmp+=url;
  10. return strtmp.c_str();
  11. }
  12. BOOST_PYTHON_MODULE(pyUtil)
  13. {
  14. def("Recognise", Recognise);
  15. }


所有示例都在Microsoft Windows XP Professional + Microsoft Visual Studio .NET 2003 + Python2.4环境下测试通过,本文所用的Boost库为1.33版本。

参考资料

  1. Python Documentation Release 2.4.1. 2005.3.30,如果您以默认方式安装了Python2.4,那么该文档的位置在C:\Program Files\Python24\Doc\Python24.chm;
  2. Michael Dawson. Python Programming for the Absolute Beginner. Premier Press. 2003;
  3. Mark Lutz. Programming Python, 2nd Edition. O''Reilly. 2001.3 ;
  4. Mark Hammond, Andy Robinson. Python Programming on Win32. O''Reilly. 2000.1 ;
Python主页:http://www.python.org;
Boost库主面:www.boost.org;

附1 text.txt

this is test text in text.txt.

附2 mymod.py

  1. import string
  2. message = ''original string''
  3. message =message+message
  4. msg_error=""
  5. try:
  6. text_file = open("text.txt", "r")
  7. whole_thing = text_file.read()
  8. print whole_thing
  9. text_file.close()
  10. except IOError, (errno, strerror):
  11. print "I/O error(%s): %s" % (errno, strerror)
  12. def transform(input):
  13. #input = string.replace(input, ''life'', ''Python'')
  14. return string.upper(input)
  15. def change_msg(nul):
  16. global message #如果没有此行,message是函数里头的局部变量
  17. message=''string changed''
  18. return message
  19. def r_file(nul):
  20. return whole_thing
  21. def get_msg(nul):
  22. return message

附3 simplepy.h

  1. #ifndef _SIMPLEPY_H_
  2. #define _SIMPLEPY_H_
  3. // simplepy.h v1.0
  4. // Purpose: facilities for Embedded Python.
  5. // by hujinshan @2005年9月2日9:13:02
  6. #include
  7. using std::string;
  8. #include
  9. //--------------------------------------------------------------------
  10. // Purpose: ease the job to embed Python into C++ applications
  11. // by hujinshan @2005年9月2日9:13:18
  12. //--------------------------------------------------------------------
  13. class CSimplepy // : private noncopyable
  14. {
  15. public:
  16. ///constructor
  17. CSimplepy()
  18. {
  19. Py_Initialize();
  20. pstr=NULL, pmod=NULL, pdict=NULL;
  21. pfunc=NULL, pargs=NULL;
  22. }
  23. ///destructor
  24. virtual ~CSimplepy()
  25. {
  26. Py_Finalize();
  27. }
  28. ///import the user module
  29. bool ImportModule(const char* mod_name)
  30. {
  31. try{
  32. pmod = PyImport_ImportModule(const_cast(mod_name));
  33. if(pmod==NULL)
  34. return false;
  35. pdict = PyModule_GetDict(pmod);
  36. }
  37. catch(...)
  38. {
  39. return false;
  40. }
  41. if(pmod!=NULL && pdict!=NULL)
  42. return true;
  43. else
  44. return false;
  45. }
  46. ///Executes the Python source code from command in the __main__ module.
  47. ///If __main__ does not already exist, it is created.
  48. ///Returns 0 on success or -1 if an exception was raised.
  49. ///If there was an error, there is no way to get the exception information.
  50. int Run_SimpleString(const char* str)
  51. {
  52. return PyRun_SimpleString(const_cast(str) );
  53. }
  54. ///PyRun_String("message", Py_eval_input, pdict, pdict);
  55. ///Execute Python source code from str in the context specified by the dictionaries globals.
  56. ///The parameter start specifies the start token that should be used to parse the source code.
  57. ///Returns the result of executing the code as a Python object, or NULL if an exception was raised.
  58. string Run_String(const char* str)
  59. {
  60. char *cstr;
  61. pstr = PyRun_String(str, Py_eval_input, pdict, pdict);
  62. if(pstr==NULL)
  63. throw ("when Run_String, there is an exception was raised by Python environment.");
  64. PyArg_Parse(pstr, "s", &cstr);
  65. return string(cstr);
  66. }
  67. ///support olny one parameter for python function, I think it''s just enough.
  68. string CallObject(const char* func_name, const char* parameter)
  69. {
  70. pfunc=NULL;
  71. pfunc = PyObject_GetAttrString(pmod, const_cast(func_name));
  72. if(pfunc==NULL)
  73. throw (string("do not found in Python module for: ")
  74. +func_name).c_str();
  75. char* cstr;
  76. pargs = Py_BuildValue("(s)", const_cast(parameter));
  77. pstr = PyEval_CallObject(pfunc, pargs);
  78. if(pstr==NULL)
  79. throw ("when PyEval_CallObject, there is an exception was raised by Python environment");
  80. PyArg_Parse(pstr, "s", &cstr);
  81. return string(cstr);
  82. }
  83. //PyObject *args;
  84. //args = Py_BuildValue("(si)", label, count); /* make arg-list */
  85. //pres = PyEval_CallObject(Handler, args);
  86. protected:
  87. PyObject *pstr, *pmod, *pdict;
  88. PyObject *pfunc, *pargs;
  89. };
  90. #endif // _SIMPLEPY_H_
  91. // end of file

2009/03/20

C++和Python的相互调用

没有评论:
c++和python的互相调用


简单配置如下:

python安装目录: C:\Python26
头文件包含:
VStudio->Tools->Options->Directories->Include files 加入 C:\PYTHON26\INCLUDE
库文件包含:
VStudio->Tools->options->Directories->Library files 加入 C:\PYTHON26\LIBS

如果是debug版本,有可能会提示can't open file "python26_d.lib"没有调试版本的类库.
Solution: 把C:\Python26\libs\python26.lib复制一个python26_d.lib即可
否则直接用release版本就行; Or change python26_d.lib to python26.lib in "pyconfig.h" file, and comment "#define Py_DEBUG".


工程文件中包含了c++调用python中的函数,也同时把c++的函数做成了dll,以供python之调用;
所以也就发生另个一个问题,c++调用python时,最后关闭了python解释器
Py_Finalize(); 以至于python又调用dll时,发生错误;所以在生成dll时,注释掉
Py_Initialize();以及Py_Finalize();


若没有装VC,可以去微软网站下一个C++的编译器 VCTookitSetup.exe.
Under VC->VStudio Tools-> VStudio 2005 command prompt , 执行命令 cl cfile编译。


举例:

1、C中调用PYTHON
  #include
  int main(int argc, char *argv[])
  {
  Py_Initialize();
  PyRun_SimpleString("from time import time,ctime\n"
  "print 'Today is',ctime(time())\n");
  Py_Finalize();
  return 0;
  }
  直接用CL 文件名 编译就是

2、
PYTHON调用由C生成的DLL
  C代码:如FOO.C
  #include
  /* Define the method table. */
  static PyObject *foo_bar(PyObject *self, PyObject *args);
  static PyMethodDef FooMethods[] = {
  {"bar", foo_bar, METH_VARARGS},
  {NULL, NULL}
  };
  /* Here's the initialization function. We don't need to do anything
  for our own needs, but Python needs that method table. */
  void initfoo()
  {
  (void) Py_InitModule("foo", FooMethods);
  }
  /* Finally, let's do something ... involved ... as an example function. */
  static PyObject *foo_bar(PyObject *self, PyObject *args)
  {
  char *string;
  int len;
  if (!PyArg_ParseTuple(args, "s", &string))
  return NULL;
  len = strlen(string);
  return Py_BuildValue("i", len);
  }
  C定义文件:foo.def
  EXPORTS
  initfoo
  编译生成foo.dll
  cl -c foo.c;
  link foo.obj /dll /def:foo.def /OUT:foo.dll
将foo.dll 改名为 foo.pyd
  在PYTHON中调用:
  import foo
  dir(foo)
  …
  即可以看到结果:
  >>> import foo
  >>> dir(foo)
  ['__doc__', '__file__', '__name__', 'bar']
  >>> ^Z
为简化python使用C的数据类型,可以 import ctypes . it is better over pyrex .


3 C调用由python生成的dll
写一个C程序,该程序存放调用python的函数接口。然后将该C程序和python程序一起做成DLL即可。


主要参考

C++ 扩展和嵌入 Python
http://www.vckbase.com/document/viewdoc/?id=1540

2009/03/08

ctypes, pyrex and Boost

没有评论:
ctypes 是为方便python程序调用C dll程序的接口而规范数据类型。
-ctypes是一个Python模块,
-可在Python中创建和操作C语言的数据类型
-可在动态链接库中传递参数到C的函数中去

Pyrex 是将Python脚本转化为可编译的C代码,以便高效执行和被C程序调用。
- 它有多出的语法(除与python兼容外)
- 它需要 pyrexc test.pyx 生成 C代码 test.c
- 然后编译成 test.so 或 test.dll

Boost_python是方便写python程序调用C dll.


相对来说 ctypes使用较方便! 使用pyrex,如果需要在Python代码访问C代码的Struct和Union,比较麻烦。

cytpes tutorial

Pyrex - a Language for Writing Python Extension Modules

pyrex一例
1,先生成简单的
//test.h
int tadd(int a, int b);

//test.c
#include "test.h"
int tadd(int a, int b) { return a+b; };

gcc -c test.c #生成test.o
ar -rsv libtest.a test.o #生成了 libtest.a 静态库

2 测试lib是否可用
// ttest.c
#include
#include "test.h"
void main(int argc, void * argv[])
{ int c=1; c = tadd(1, 4); printf("c = %d \r\n", c); }

gcc ttest.c -ltest -L. #生成了a.out
./a.out #结果是: c = 5

证明我们的lib库是可以正常工作的


3,写一个python的模块td.pyx,调用它libtest里的tadd()函数
#td.pyx
cdef extern from "test.h":
int tadd(int i, int j)

def tdadd(int i, int j):
cdef int c
c=tadd(i, j) #在这行调用c=tadd(i, j)
return c

编译:
pyrexc td.pyx #生成 td.c
gcc -c -fPIC -I/usr/include/python2.4/ td.c #生成td.o
gcc -shared td.o -ltest -L. -o td.so #生成了td.so。这个就是python可以用的模块so

安装 pyrex,略。
测试:
import td
dir(td)
['__builtins__', '__doc__', '__file__', '__name__', 'tdadd']
td.tdadd(1,2)
3

OK。

2009/02/13

Ubuntu 8.10下如何升级eric4-python到4.3.0

没有评论:
Ubuntu下的python IDE 软件:
gedit虽然已经很好了,可还是想要一个集成开发环境。ubuntu下的
Eric python IDE 似乎还行。
Stani's Python Editor: another choice 还行,但不能 create project.
PyPE : not good
vim 但没有集成环境
sudo apt-get install vim-full vim-python
最终选用 Eric Python Editor
升级ubuntu from 8.04 to 8.10后,发现eric-python 不再能 auto python code completion (出现提示窗口,但不能选择!)。

解决方案: 重新安装eric4-4.3.0

0. uninstall previous eric4.1.0 from synaptic

1. download eric4 package from http://eric-ide.python-projects.org/eric4-download.html

2. sudo apt-get install python-qt4-dev python-qscintilla2

3. cd to eric-package directory
sudo python install.py
若提示:
Please enter the name of the Qt data directory.
(That is the one containing the 'qsci' subdirectory.)
>>
输入 /usr/share/qt4

4. 运行.
目前ubuntu source 未包含最新eric版本,因此在terminal 执行eric4 (位于/usr/local/bin/eric4)

Note: 目前eric4.3在laptop上窗口显示有问题。

2008/10/01

Install CGAL and CGAL-python

没有评论:
0. Prerequisites
Boost http://www.boost.org
sudo apt-get install libboost-python1.34.1
GMP http://gmplib.org/
sudo apt-get install python-gmpy # will also install libgmp3c2
MPFR http://www.mpfr.org/
(search in synaptic )
1. Install CGAL 3.3.1
sudo apt-get install libcgal2 libcgal-dev libcgal-demo
or
Goto http://www.cgal.org/cgi-bin/cgal_download.pl
./install_cgal -i

2. Install CGAL-python 0.9.3
https://gforge.inria.fr/frs/?group_id=320
follow "readme" instruction.
Homepage: http://cgal-python.gforge.inria.fr/

图简单,可以安装 0.9.1版本。在http://amcg.ese.ic.ac.uk/~pfarrell/python-cgal/ 有一个python-cgal 0.9.1的deb安装包,可用!


安装 python-cgal 0.9.3 (with Ubuntu 8.10, python2.5)

按readme安装后,输入
$python
>>> from CGAL.Triangulations_2 import *
出现如下错误:
Traceback (most recent call last):
File "", line 1, in
File "CGAL/__init__.py", line 3, in
from Kernel import *
ImportError: CGAL/Kernel.so: undefined symbol: _ZN4CGAL8ROTATIONE

代替make, 用Patrick Farrell写的一个安装程序 http://lists.gforge.inria.fr/pipermail/cgal-python-users/attachments/20080910/8d96239f/setup.py

Put it in your CGAL-python source directory and type:

python setup.py build
sudo python setup.py install
and it works.


---------------------------------------------------
#setup.py
from distutils.core import setup
from distutils.extension import Extension
import os
import os.path
import glob

# Author: Patrick Farrell
# patrick.farrell06@imperial.ac.uk

def MakeExtension(directory):
try:
os.stat(os.path.join("bindings", directory, "All_files_at_once.cpp"))
files = [os.path.join("bindings", directory, "All_files_at_once.cpp")]
except OSError:
files = glob.glob(os.path.join("bindings", directory, "*.cpp"))

ext = Extension(
"CGAL/%s" % directory,
files,
include_dirs=["../.."],
libraries=["CGAL", "boost_python", "gmp", "mpfr"],
define_macros=[('CGAL_DONT_USE_LAZY_KERNEL', None)]
)
return ext

directories = [directory for directory in os.listdir("bindings") if os.path.isdir(
os.path.join("bindings", directory))]
extensions = [MakeExtension(directory) for directory in directories]

setup(
name='CGAL-Python',
version='0.9',
description="Python bindings for the Computational Geometry Algorithms Libra
ry",
author = "CGAL team",
url = "http://cgal-python.gforge.inria.fr/",
packages=["CGAL"],
package_dir={"CGAL": "cgal_package/CGAL"},
ext_modules=extensions,
)

---------------------------------------------------


CGAL-Python is a collection of python modules corresponding to CGAL.
Currently CGAL-Python contains the following modules:
  • CGAL.Kernel: Point_2 , Point_3 ....
  • CGAL.Triangulations_2: Triangulation_2, Delaunay_triangulation_2, Constrained_triangulation_2 ...
  • CGAL. Triangulations_3: Triangulation_3, Delaunay_triangulation_3
  • CGAL.Mesh_2
  • CGAL. Geometric_Optimisation: Min_annulus_2, Min_annulus_3, Min_circle_2, Min_ellipse_2 , Min_sphere_2, Min_sphere_3
  • CGAL.Alpha_shapes_2(3)
  • CGAL.Polyhedron
  • CGAL.Convex_hull_2
To use CGAL as Python package you have to import the module you expect to use by typing :
from CGAL import * # this will import the whole CGAL.
from CGAL.Kernel import * # you have to import this module.

Example:
----------------------------------------------------------------------
from CGAL.Kernel import *
from CGAL.Triangulations_2 import *
from random import *
dt = Delaunay_triangulation_2()
vert = {}
for i in range(20):
vert[i] = dt.insert(Point_2(random(),random()))
# the finite vertices:
for v in dt.vertices:
print v.point()
# the finite edges
for e in dt.edges:
print e.vertex()
# the finite faces
for f in dt.faces:
for i in range(3): print f.vertex(i).point()
# compute the finite faces incident to Vertex = vert[0]
finites_faces = []
f1 = cir_faces.next()
if dt.is_infinite(f1) == False:
finites_faces.append(f1)
for f in cir_faces:
if f == f1:break

finites_faces.append(f)
---------------------------------------------------------------

Other useful packages under Ubuntu:
pyste是boost.python自带的代码生成器,利用pyste可以很方便的为c++ 的 lib加一层python的shell。pyste依赖gccxml. dependent on boost
mapnik 地图渲染引擎,其渲染的地图效果堪和googlemaps媲美. 里面的底层绘制是使用Agg库,Agg是一个高效的2D图形引擎库. python-mapnik, dependent on boost

geomview http://www.geomview.org 画二维图最好用GnuPlot,而画三维图的时候最好用geomview


----

2008/08/08

一个解读Bluetooth GPS的python程序

没有评论:
在NMEA GPS receiver中,GPGGA is not the only one to read GPS position, with all receivers, since not all receiver use it.

Should be able decode at least :
GPGGA
GPRMC
GPGLL
(注: 那些含有lon&lat的 sentence应该都可以)

Download and review Python for Series 60 Documentation bundle at http://forum.nokia.com/main/0,6566,040,00.html?fsrParam=1-3-/main/0,,034-821,00.html&fileID=6534

At "Programming with Python for Series 60 Platform" there is section dedicated to the topic - Bluetooth Sockets. There is example of services discovery and reference to Python's Bluetooth console and Bluetooth socket stdio.

Here is a sample BT program that reads a position from a BT GPS and displays it.

import socket
class BTReader:
def connect(self):
self.sock=socket.socket(socket.AF_BT,socket.SOCK_STREAM)
address,services=socket.bt_discover()
print "Discovered: %s, %s"%(address,services)
target=(address,services.values()[0])
print "Connecting to "+str(target)
self.sock.connect(target)

def readposition(self):
try:
while 1:
buffer=""
ch=self.sock.recv(1)
while(ch!='$'):
ch=self.sock.recv(1)
while 1:
if (ch=='\r'):
break
buffer+=ch
ch=self.sock.recv(1)

if (buffer[0:6]=="$GPGGA"):
(GPGGA,hhmmssss,l1ddmmmmmm,l1,l2dddmmmmmm,l2,q,xx,pp,ab,M,cd,M,xx,nnnn)=buffer.split(",")
return (l1+l1ddmmmmmm, l2+l2dddmmmmmm)
except Error:
return None

def close(self):
self.sock.close()

bt=BTReader()
bt.connect()
print bt.readposition()
print bt.readposition()
print bt.readposition()
bt.close()

gps and gsm locations from python s60

没有评论:
Goal: periodically obtain 1) BT GPS (i.e. $GPRMC and $GPGGA sentences) and 2) GSM cell id at the same time and save.

____________________________________

# Simple BT App
#$GPRMC,161229.487,A,3723.2475,N,12158.3416,W,0.13,309.62,120598, ,*10

import socket,location,urllib

class BTReader:

def connect(self):
self.sock=socket.socket(socket.AF_BT,socket.SOCK_STREAM)
address,services=socket.bt_discover()
print "Discovered: %s, %s"%(address,services)
target=(address,services.values()[0])
print "Connecting to "+str(target)
self.sock.connect(target)

def readposition(self):
try:
buffer=""
ch = self.sock.recv(1)
while(ch !='\n'):
buffer+=ch
ch = self.sock.recv(1)
# print buffer

if (buffer[0:6]=="$GPRMC"):
(GPRMC,utc,status,lat,latns,lon,lonew,knots,course,date,xx1,xx2)=buffer.split(",")
return "GPS (%s,%s,%s,%s,%s)"%(utc,lat+latns,lon+lonew,knots,course)
except Error:
return "Error!\n"
return ""

def close(self):
self.sock.close()

class GSM_loc:

def upd(self):
self.loc = location.gsm_location()
return "GSM (MCC:%s MNC:%s LAC:%s CID=%s)"%(self.loc[0], self.loc[1], self.loc[2], self.loc[3])

gsm = GSM_loc()

bt=BTReader()
bt.connect()

i=0
while (i<15):
print gsm.upd()
print bt.readposition()
i+=1

bt.close()

在nokia s60手机上编写 python 程序

没有评论:

s60: 为symbian os 的手机操作系统.这种可编程的手机通常称智能手机,如我的手机nokia 7610。
PyS60:Python for S60

手机上安装 PyS60

下载点 http://sourceforge.net/projects/pys60/%E4%B8%8B%E8%BD%BD
* PythonForS60_1_3_20_2ndEd.SIS - PyS60
* PythonScriptShell_1_3_20_2ndEd.SIS - Python shell 否则没有运行界面

开发环境的选取

方法1。在windows里面写python程序。保存,手机拔卡,用读卡器把程序放到卡里,手机插卡,然后运行python for s60 然后运行脚本。调试起来比较麻烦。也可用bluetooth console传数据。

Q:Symbian python程序是否可以制作成独立软件包(sis)?
A:可以,使用Symbian Python SDK里面带的py2sis.exe.
用法:

py2sis.exe python程序名.py sis文件名称.sis --uid=0x12345678
例子:

E:\Nokia\Tools\Python_for_Series_60\py2sis>py2sis.exe sms.py smskiki.sis --uid=0x100039Cf
注意:目标文件名一定要添加sis后缀,不然会出现error: invalid destination file

方法2。安装nokia的sdk,这样就构造了一个模拟器,然后从模拟器里面安装python。
PythonForS60_1_3_20_SDK_2ndEd.SIS - SDK 开发环境,可不装,用 wxpython+pys60 emulation开发

方法3。wxPython 模拟器 (推荐)
和nokia sdk模拟器不同的是,PyS60 emulation library利用wxPython gtk只写了主要两个图形包例如appuifw,e32。appuifw继承了wx的图形类。

software:
* python2.4 当然需要 (from http://www.python.org/ftp/python/2.4.3/python-2.4.3.msi)
* PyS60 emulation library (4 files: "appuifw.py, e32.py, graphics.py, key_codes.py")
* wxPython (for win32 or linux, www.wxpython.org )

windows 下安装:
安装办法:先去下载python 2.4,然后再去下载wxPython。然后下这个模拟器,把里面的四个py文件放到C:\Python2.4\Lib下。(具体放到哪里得看你的Python的安装目录了)

Ubuntu 下安装:
- wxPython
(copied from http://wxpython.org/download.php#binaries)
Add the following to your /etc/apt/sources.list file:

# wxPython APT repository at wxcommunity.com
deb http://wxpython.wxcommunity.com/apt/ubuntu/dapper /
deb-src http://wxpython.wxcommunity.com/apt/ubuntu/dapper /

After the repository info has been added to /etc/apt/sources.list you can fetch and install the packages using one of the GUI package manager tools such as Synaptic or Adept, or by running the following commands from a terminal window:

sudo apt-get update
sudo apt-get install python-wxgtk2.8 python-wxtools wx2.8-i18n

- pys60 compact library
put 4 files to PYTHONPATH directory, which is normally /usr/lib/python2.x. Show PYTHONPATH in "import sys, print sys.path".

手机与电脑之间的文件传输、控制

方法1:蓝牙控制台

能够让你通过个人电脑连接你手机上的Python命令行并执行命令。

  1. 在你的PC上打开比如一个超级中端(确定你已经安装了蓝牙设备并为超级终端选择了正确的端口)。
  2. 在你的手机上运行python -> optoins -> Bluetooth console。现在一个蓝牙连接将会被激活,python命令行将会显示在超级终端上

方法2。MIT PUTools: 使用bluetooth 在手机和pc之间传数据,实现同步。可以在PC上编程序,然后整个传到手机上去run over bluetooth。网址是http://people.csail.mit.edu/kapu/symbian/python.html

一个显示输入对话框的程序:

import appuifw
import e32

def bexit():
app_lock.signal()
def addtext():
t = appuifw.query(u'Input text:','text')
r.add(unicode(t))
r = appuifw.Text()
r.set(u'info:\n')
appuifw.app.screen = 'normal'
appuifw.app.menu = [(u'Add',addtext),(u'Exit',bexit)]
appuifw.app.body = r
appuifw.app.exit_key_handler = bexit
app_lock = e32.Ao_lock()
app_lock.wait()

保存成1.py然后直接用python执行。。。

sample2: take photo and save

import camera
import graphics
img=camera.take_photo()
img.save("test.jpg")

Note: 如果有gps receiver with bluetooth, 可以在拍照的同时记录下照片经纬度

2008/07/30

Ubuntu: LAMP 安装

没有评论:

LAMP套件就是Linux+Apache+Mysql+PHP这四款软件,组成了一个可以使网站运行的套装工具软件。其中P也可代指 PHP/Python/Perl。如果只用后台数据处理,可以考虑用python编写。当然python 也有网页功能。

版本:
Apache 2
Mysql 5.0
Php 5.1

1.搭建基本的web环境,我使用的是apache2 + php5 + mysql 5.0
sudo apt-get install apache2 mysql-server php5-mysql
2.(optional)解决用户登录时图形验证码无法显示的问题
apt-get install php5-gd
3. 安装mysql的web管理软件phpmyadmin
apt-get install phpmyadmin
4. 基于浏览器的图形化管理工具软件 webwin (http://www.webwin.com)

MySQL更改root密码
刚安装mysql后可执行 mysql -u root -p 加上密码。
方法1:
shell>mysqladmin -u root password new_password

方法2:
mysql> SET PASSWORD FOR root=PASSWORD(’new_password’);

方法3:使用 mysqladmin命令
shell> mysql -u root
mysql> UPDATE user SET Password=PASSWORD(’new_password’) WHERE user=’root’;
mysql> FLUSH PRIVILEGES;