Google

星期一, 四月 27, 2009

使用Moblin进行应用程序开发——Clutter之Event[转]

上次的Demo太简单了,仅仅在窗口中铺了一堆图片,用户只能看,却不能动。这次我们要给之前的Demo增加一个功能:支持鼠标拖动。

这次我们会接触到clutter的事件机制。Actor可以接受输入的事件,比如键盘按键、鼠标移动等事件,并且可以通过回调函数对事件进行处理。由于这一套机制是通过glibsignal来实现的,因此熟悉glibgtk编程的用户对此肯定是相当的熟悉。但是与gtk相比,clutter还是有一点不太相同的地方,就是除了Stage之外,所有的Actor默认不接受事件。如果需要让某个Actor接受事件,程序员需要通过clutter_actor_set_reactive()函数手动的将Actor设为reactive,也就是说能够接受事件。我猜想这样的设计是为了减少事件处理时寻找事件源所花费的时间。

    下图是从clutter参考手册中截下来的,每一个有“?”标记的地方用户都可以插入有关的事件处理的代码。

http://software.intel.com/zh-cn/blogs/2009/04/20/moblinclutterevent/?cid=sw:prccsdn652

标签: ,

星期二, 四月 07, 2009

捕捉一个对象的属性

python , __getattr__

捕捉一个对象的属性

>>> class F:
... def __getattr__(self,attr):
... if attr=='abc':
... return "got it !"
...
>>> f= F()
>>> f.abc
'got it !'

http://www.okpython.com/bbs/thread-696-1-1.html

标签:

Python XMLRPC with GBK encoding

一句话,简直是噩梦,如果实在是没有什么理由非要用GBK编码不可,我的建议,还是改用utf-8这样更国际化的标准吧。说实在的,Python下面折腾GBK编码的XMLRPC实在是没有什么意思,没有任何乐趣,只有浪费时间。

  言归正传,当你没有办法非要使用GBK编码的xmlrpc服务,体会一下恶梦,那我们就开始吧。首先明确一下革命形势:标准的Python xmlrpclib库,就是不支持GBK编码的。换而言之,指望通过给ServerProxy指定encoding参数的做法,是解决不了什么问题的。问题的关键在于,Python XML模块的底层,依赖的expat这个东东,对GBK支持是有问题的(我是想说更本就不支持,不过不能确定,就暂且定义为有问题),所以只要是依赖这个东西的XML模块,都是不能很好的处理GBK编码下的XML数据的。解决问题的大体方向就出来了,一个是绕过expat,干脆不用这个东西,其二就是认命妥协了,把数据转换成utf-8编码再塞给expat吧。前面一个方案,可联想到的就是libxml2-python。我是采用第二种方案了,这里也有两种可参考的做法,一种是自己定义一个Parser,然后覆盖ServerProxy那个getParser,生成支持转码功能的XMLParser给xmlrpc proxy使用。另外一个办法,就是干脆跳过ServerProxy,自己做一个。考虑到我的实际使用情况,不会有太大的数据传输,没有必要做一个支持流接口的XMLParser,所以就干脆自己重新做了一个代替ServerProxy的东西。下面是简单的代码示例。

  PYTHON:

  importxmlrpclib

  importhttplib

  

  defXMLRPCCall0(URI, methodname, param):

  body = xmlrpclib.dumps(

  param, methodname, False, 'GBK')

  

  (protocl, host, path,

  query, fragment)= httplib.urlsplit(URI)

  h = httplib.HTTPConnection(host)

  headers = {

  'Content-Type': 'text/xml'

  }

  h.request('POST', URI, body, headers)

  res = h.getresponse()

  resbody = res.read()

  h.close()

  resbody = resbody.replace(' encoding="GBK"', '')

  returnxmlrpclib.loads(

  resbody.decode('GBK').encode('utf-8'))[0][0]

http://www.cnscn.org/htm_data/369/0810/17233.html

标签: , ,

xmlrpc for python

使用python处理xmlrpc太简单了,又一次感受到了python的力量!
下面以使用python调用wordpress提供的xmlrpc方法为例简单介绍一下:

1) how to call xmlrpc method in python
>>> import xmlrpclib
>>> from pprint import pprint
>>> server = xmlrpclib.ServerProxy("http://localhost/wordpress/xmlrpc.php")
>>> pprint(server.system.listMethods() )

['system.multicall',
'system.listMethods',
'system.getCapabilities',
'demo.addTwoNumbers',
'demo.sayHello',
'pingback.extensions.getPingbacks',
'pingback.ping',
'mt.publishPost'......]

>>> blogs = server.metaWeblog.getRecentPosts('','admin','passwd',5)
>>> pprint(blogs)
>>> print(blogs[2]['permaLink'])

http://localhost/wordpress/?p=135

2)how to setup a xmlrpc server in python

import calendar, SimpleXMLRPCServer
#The server object
class Calendar:
def getMonth(self, year, month):
return calendar.month(year, month)

def getYear(self, year):
return calendar.calendar(year)
calendar_object = Calendar()
server = SimpleXMLRPCServer.SimpleXMLRPCServer(("localhost", 8888))
server.register_instance(calendar_object)
#Go into the main listener loop
print "Listening on port 8888"
server.serve_forever()

3)write a client to test server above
import xmlrpclib
server = xmlrpclib.ServerProxy("http://localhost:8888")
month = server.getMonth( 2002, 8 )
print month

August 2002
Mo Tu We Th Fr Sa Su
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

PS:
pprint means pretty print. A cool tool too.

Reference:
1 http://docs.python.org/lib/module-xmlrpclib.html
2 http://www-128.ibm.com/developerworks/library/ws-pyth10.html
3 http://groovy.codehaus.org/XMLRPC

http://zeaster.blogspot.com/2007/01/xmlrpc-for-python.html

标签: , ,

星期四, 四月 02, 2009

命令行发送邮件clmail

有同学想在命令行下发邮件,鉴于《雅奇MIS》大师版目前未开放email功能,写了这个命令行工具,目前就是可以用而已。

当然要使用需要2步:

安装python 2.5
复制clmail.py到系统path变量指向的目录,或者复制到某目录,将其添到path中。

执行clmail.py ...就可以了。

详细内容见:

http://www.oulan.com/clmail/

标签: ,

星期一, 三月 30, 2009

如何使用Python发送带附件的邮件

1、首先要理解一个常识(RFC)
RFC(The Request for Comments)是一个关于Internet各种标准的文档,定义了很多的网络协议和数据格式,标准的Internet邮件遵从RFC2822(Internet Message Format)等几个文档,其中RFC822中描述了邮件头(mail headers)的格式。具体文档在Python帮助里都可以查到全文。
2、其次要熟悉Python的几个模块
关于邮件的有email,smtplib等,关于编码的有base64,binascii等,发送邮件的方式就是先根据RFC构造好邮件的各个部分,然后登录到smtp服务器sendmail就可以了。
3、下面贴代码
1# -*- coding: cp936 -*-
2
3from email.Header import Header
4from email.MIMEText import MIMEText
5from email.MIMEMultipart import MIMEMultipart
6import smtplib, datetime
7
8#创建一个带附件的实例
9msg = MIMEMultipart()
10
11#构造附件
12att = MIMEText(open('d:\\tc201.rar', 'rb').read(), 'base64', 'gb2312')
13att["Content-Type"] = 'application/octet-stream'
14att["Content-Disposition"] = 'attachment; filename="tc201.rar"'
15msg.attach(att)
16
17#加邮件头
18msg['to'] = 'zhousl@xxx.com'
19msg['from'] = 'zhousl@xxx.com'
20msg['subject'] = Header('冒烟测试结果 (' + str(datetime.date.today()) + ')', \
21 'gb2312')
22#发送邮件
23server = smtplib.SMTP('smtp.xxx.com')
24server.sendmail(msg['from'], msg['to'], \
25 msg.as_string())
26server.close
4、几个值得注意的地方
1)构造附件时注意采用正确的字符集,这个困惑我好久,开始没有用gb2312,发过去的压缩文件就是坏的;
2)上面的代码中没有包括登录smtp服务器的指令,而Internet上面的smtp服务器一般都是要求认证的,可以通过smtp.login方法进行登陆
3)sendmail方法中的参数to可以是包含多个地址的元组,这样可以发送邮件给多个人了
4)Python2.4以前的版本是不支持gb2312字符集的,要下载安装Python2.4才能跑上面的代码,当然2.4.1肯定会更好一点

http://www.cnblogs.com/zhousl/archive/2005/12/13/296167.html

标签: ,

Python:使用getopt模块处理命令行参数

可以参考http://docs.python.org/lib/module-getopt.html

# -*- coding: cp936 -*-
import getopt
import sys

def usage():
print '''Help Information:
-h: Show help information
-xValue:
...'''

if __name__=='__main__':
#set default values
x=1
y='y'

try:
print sys.argv[1:]
opts,args=getopt.getopt(sys.argv[1:],'hx:y:d')
#opts 是带-选项的参数
#args 是没有选项的参数
print opts
print args
#h表示使用-h,h选项没有对应的值
#x:表示你要使用-xValue,x选项必须有对应的值.
except getopt.GetoptError:
#打印帮助信息并退出
usage()
sys.exit(2)
#处理命令行参数
for o,a in opts:
if o=='-h':
usage()
sys.exit()
if o=='-x':
try:
x=x+int(a) #注意默认a为字符串
except ValueError:
print 'Invalid Value'
print x
if o=='-d':
print 'use -d'
if o=='-y':
y=y+a

运行结果:
getopt_example.py -x12 -y ss -d sdf s123
['-x12', '-y', 'ss', '-d', 'sdf', 's123']
[('-x', '12'), ('-y', 'ss'), ('-d', '')]
['sdf', 's123']
13
use -d

http://hi.baidu.com/javalang/blog/item/1f72fe034fb9de743812bb7e.html

标签:

星期一, 十二月 29, 2008

vnc2swf Screen Recorder

Vnc2swf is a cross-platform screen recording tool for ShockWave Flash (swf) or Flash Video (flv) format.


http://davidf.sjsoft.com/files/pyvnc2swf/

标签: , , , ,

星期三, 十月 08, 2008

libcurl for Python

* libcurl is a free and easy-to-use client-side URL transfer library, supporting FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE and LDAP. libcurl supports HTTPS certificates, HTTP POST, HTTP PUT, FTP uploading, kerberos, HTTP form based upload, proxies, cookies, user+password authentication, file transfer resume, http proxy tunneling and more!

* libcurl is highly portable, it builds and works identically on numerous platforms, including Solaris, NetBSD, FreeBSD, OpenBSD, Darwin, HPUX, IRIX, AIX, Tru64, Linux, Windows, Amiga, OS/2, BeOs, Mac OS X, Ultrix, QNX, OpenVMS, RISC OS, Novell NetWare, DOS and more...

* libcurl is free, thread-safe, IPv6 compatible, feature rich, well supported and fast.
http://pycurl.sourceforge.net/

urlgrabber is a pure python package that drastically simplifies the fetching of files. It is designed to be used in programs that need common (but not necessarily simple) url-fetching features. It is extremely simple to drop into an existing program and provides a clean interface to protocol-independant file-access. Best of all, urlgrabber takes care of all those pesky file-fetching details, and lets you focus on whatever it is that your program is written to do!

urlgrabber came into existence as the part of yum that downloads rpms and header files, but it quickly became clear that this is a general problem that many applications must deal with.

urlgrabber

标签: , , ,

星期二, 九月 09, 2008

Python文摘,IP地址和数值转换

>>> socket.inet_ntoa(struct.pack('I',socket.htonl(16909060)))
'
1.2.3.4'
>>> socket.ntohl(struct.unpack("I",socket.inet_aton('1.2.3.4'))[0])
16909060
再加几个:
>>> struct.unpack("I",socket.inet_aton('1.2.3.4')) (67305985L,)
>>> socket.ntohl(67305985)16909060>>> socket.htonl(16909060)67305985>>> struct.unpack('i',socket.inet_aton('1.2.3.4'))(67305985,)
>>> struct.pack('i',16909060)
'\x04\x03\x02\x01'
>>> struct.pack('i',67305985)
'\x01\x02\x03\x04'
>>> socket.inet_ntoa(struct.pack('I',socket.ntohl(16909060)))
'1.2.3.4'
>>> socket.htonl(struct.unpack("I",socket.inet_aton('1.2.3.4'))[0])
16909060
这样很好玩吧~
(1). inet_aton 将ip地址的4段地址分别进行2进制转化,输出用16进制表示:
1.2.3.4 ——inet_aton——> 0000 0001,0000 0010,0000 0011,0000 0100
(2).unpack的处理是按16进制(4bit)将2进制字符,从后向前读入的,低位入,处理成:
00000100 00000011 00000010 00000001
也就是 4 3 2 1
pack也一样,从后向前读入字符,所以——
用16进制表示的1 2 3 4(16909060)打包成 4 3 2 1 的顺序;
用16进制表示的4 3 2 1(67305985)打包成 1 2 3 4 的顺序;
(3) ntohl, htonl 表示的是网络地址和主机地址之间的转换(network byte host byte)
由于unpack/pack的解/打包的颠倒顺序,必须通过htonl 或者 ntohl 进行处理。
(4) network byte, host byte
这2个名词折腾半天,host byte 由于处理器的方式不同 little-endian或者big-endian,将ip地址转换的最终输出是不一样的,参考(http://www.informit.com /articles/article.aspx?p=169505&seqNum=4 )
(http://www.netrino.com/Embedded-Systems/How-To/Big-Endian-Little-Endian)
big-endian: 最高位在左边(内存存储空间的最低位)
little-endian: 最高位在右边(内存存储空间的最低位)
i386-unknown-freebsd4.8: little-endian
powerpc-apple-darwin6.6: big-endian
sparc64-unknown-freebsd5.1: big-endian
powerpc-ibm-aix5.1.0.0: big-endian
hppa1.1-hp-hpux11.11: big-endian
i586-pc-linux-gnu: little-endian
sparc-sun-solaris2.9: big-endian
而为了统一这种传输标准(打个补丁,再创造一个名词函数),又有network byte,这个其实就是标准的big-endian;
由于x86本身的处理属于little-endian,所以上述应该按照标准的network byte 进行处理,这样可避免cpu造成的不同:
socket.htonl(struct.unpack("I",socket.inet_aton('1.2.3.4'))[0])
socket.inet_ntoa(struct.pack('I',socket.htonl(16909060)))
###############################################################################
(1个64位amd+32位windows, 1个32位intel+linux, 出来的数值是一样的:
>>> socket.ntohl(struct.unpack("I",socket.inet_aton('220.194.61.32'))[0])
-591250144
>>> socket.inet_ntoa(struct.pack('I',socket.htonl(-591250144)))
'220.194.61.32'
但是64位amd+64位linux,是这样:
>>> socket.ntohl(struct.unpack("I",socket.inet_aton('220.194.61.32'))[0])
3703717152
>>> socket.inet_ntoa(struct.pack('I',socket.htonl(-591250144)))
'220.194.61.32'
>>> socket.inet_ntoa(struct.pack('I',socket.htonl(3703717152)))
'220.194.61.32'
unpack/pack和cpu,os无关;
socket.ntohl/htonl的输出结果int型 对32 os,处理成signed 类型,首位1被处理成负数;
对 64位 os,则是unsigned类型;
(晕了半天,那个值才明白是位数,和cpu不相干)
###############################################################################
(5)mysql里面的函数是inet_aton, inet_ntoa 和python的socket不同,直接实现ip string到network byte的转换,python里面只能实现ip地址到network byte的2进制转换:
mysql> select inet_aton('1.2.3.4');
-> 16909060
mysql> select inet_ntoa(16909060);
-> 1.2.3.4

http://bbs.chinaunix.net/thread-1163546-1-7.html

struct.unpack("!I", ...) 可以产生无符号数

标签: ,

星期二, 八月 26, 2008

一点有用的东西

Jabber server written in Python
http://code.google.com/p/pretzel/

Twisted 太重要了。写的非常好。
http://twistedmatrix.com/

标签: ,

Jabbers and others important

Jabber servers:

OpenFire
http://www.igniterealtime.org/projects/openfire/index.jsp

JabberIn
http://www.jabbin.com/index.html

OpenZoep: An Open Source VoIP Engine

http://www.voipster.com/

VOIP Jingle library
http://www.xmpp.org/extensions/xep-0166.html

XPCOM
http://www.mozilla.org/projects/xpcom/

http://xmpppy.sourceforge.net/

标签: , , ,

用Python操作MS Access数据库

首先,你应安装了python和Python for Windows extensions。
1、建立数据库连接
import win32com.client
conn = win32com.client.Dispatch(r'ADODB.Connection')
DSN = 'PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=C:/MyDB.mdb;'
conn.Open(DSN)
2、打开一个记录集
rs = win32com.client.Dispatch(r'ADODB.Recordset')
rs_name = 'MyRecordset'#表名
rs.Open('[' + rs_name + ']', conn, 1, 3)
3、对记录集操作
rs.AddNew()
rs.Fields.Item(1).Value = 'data'
rs.Update()
4、用SQL来插入或更新数据
conn = win32com.client.Dispatch(r'ADODB.Connection')
DSN = 'PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=C:/MyDB.mdb;'
sql_statement = "Insert INTO [Table_Name] ([Field_1], [Field_2]) VALUES ('data1', 'data2')"
conn.Open(DSN)
conn.Execute(sql_statement)
conn.Close()
5、遍历记录
rs.MoveFirst()
count = 0
while 1:
if rs.EOF:
break
else:
count = count + 1
rs.MoveNext()

注意:如果一个记录是空的,那么将指针移动到第一个记录将导致一个错误,因为此时recordcount是无效的。解决的方法是:打开一个记录集之前,先将Cursorlocation设置为3,然后再打开记录集,此时recordcount将是有效的。
例如:
rs.Cursorlocation = 3 # don't use parenthesis here
rs.Open('Select * FROM [Table_Name]', conn) # be sure conn is open
rs.RecordCount # no parenthesis here either

http://www.pythontik.com/blog/article.asp?id=23

标签: ,

关于urllib2中的Keep-Alive

http://www.nabble.com/-CPyUG:41451--%E5%85%B3%E4%BA%8Eurllib2%E4%B8%AD%E7%9A%84Keep-Alive%E5%8F%8A%E8%AF%B7%E6%95%99%E5%A5%BD%E7%94%A8%E7%9A%84http%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%8C%85-td15706978.html

标签: , ,

TGFusionCharts

TGFusionCharts is a TurboGears widget which lets you easily add FusionCharts Flash Charts to your application. TGFusionCharts is licensed under MIT License; FusionCharts has a commercial license, but offers a free trial.

http://www.thesamet.com/TGFusionCharts/
http://www.fusioncharts.com/Demos/SalesDashboard/Contents/Visits.html

标签: , ,

py2exe使用方法

一、简介

py2exe是一个将python脚本转换成windows上的可独立执行的可执行程序(*.exe)的工具,这样,你就可以不用装python而在windows系统上运行这个可执行程序。

py2exe已经被用于创建wxPython,Tkinter,Pmw,PyGTK,pygame,win32com client和server,和其它的独立程序。py2exe是发布在开源许可证下的。

二、安装py2exe

从 http://prdownloads.sourceforge.net/py2exe下载并运行与你所安装的Python对应的py2exe版本的 installer,这将安装py2exe和相应的例子;这些例子被安装在lib\site-packages\py2exe\samples目录下。

三、py2exe的用法

如果你有一个名为helloworld.py的python脚本,你想把它转换为运行在 windows上的可执行程序,并运行在没有安装python的windows系统上,那么首先你应写一个用于发布程序的设置脚本例如 mysetup.py,在其中的setup函数前插入语句import py2exe 。
mysetup.py示例如下:
# mysetup.py
from distutils.core import setup
import py2exe

setup(console=["helloworld.py"])

http://www.diybl.com/course/1_web/webjs/2007111/81629.html

标签: ,

星期一, 八月 25, 2008

孟岩《来自巴西的Lua语言新星让我脸红》及网友评论

一种自由软件的脚本语言 Lua ,由于在游戏界日益成为主流脚本语言(得到著名的卢卡斯艺术公司两款游戏采用,并在GameDev.net的调查中高居脚本语言榜首),最近引起了业界的广泛关注。
Lua (葡萄牙语,义为月亮)是一种轻量级的强大的扩展语言,用纯ANSI C编写,最初版本只有6000行代码,却实现了垃圾收集、反射、面向对象等机制。Lua 是由巴西里约热内卢天主教大学计算机系的Roberto Ierusalimschy 等人于1993年开发的。
最近,Roberto Ierusalimschy 撰写的《Programming in Lua》一书也已经出版
---tangl_99

Python是荷兰人写的,Ruby是日本人写的,Lua是巴西人写的,我这个中国人只能在这里脸红。
---孟岩

不必人人制轮胎,难道你不想躺在轮胎做的吊床上休息?
---牡蛎

只选对的,不选贵的。
---路人甲

转载自tangl_99的blog孟岩的blog

Python是荷兰人写的,Ruby是日本人写的,Lua是巴西人写的,我这个中国人只能在这里脸红。
Lua是所有动态语言中间平均效率最高的一个。它最初是以Library的形式存在,纯粹只是用作C/C++的一个扩展。现在不仅发展出了解释器,还发展 出了编译器。游戏开发里Lua是使用最广泛的脚本语言。当世界上第一本Lua图书上市销售的时候,一位读者评价道:"Lua is a real gem."
(牡蛎到没有听过Lua、Python或者Ruby的编译器——.NET的冒牌货除外)

Lua很棒,Lua是巴西人发明的,这些都令我不爽,但是还不至于脸红,最多眼红。
让我脸红的是Lua的源代码,百分之一百的ANSI C,一点都不掺杂。在任何支持ANSI C编译器的平台上都可以轻松编译通过。我试过,真是一点废话都没有。
我1996年就学会了C,1997年就跑去研究Win32 API,后来是C++,STL,Java... 直到2002年看到C Interfaces and Implementations,才知道仅仅用ANSI C就可以实现一个强大的优美的library,直到2004年看到Lua的源代码才知道仅仅用ANSI C就可以实现一个非常快的虚拟机、非常棒的解释器/编译器和非常漂亮的语言实现。
这8年我都干什么去了?
---孟岩

http://www.chinaitpower.com/2005September/2005-09-13/204728.html

标签: , , , , , , ,

星期四, 八月 21, 2008

使用xrc的一点心得

这篇文章老早就想引过来了。写得不错。

首先向大家说明,我学python才一个多月,写了一个程序主 要是为了练习python和wxPython,如果有什么不对的地方还请大家指出。我也没怎么查是否有人写过类似的说明,就当给大家一个参考。我原来写过 c++/gtk/gtkmm的程序,觉得wxPython的图形程序写起来还是很容易的,不过偶得一个同事说我的python程序写 的比较像C++程序,现在正在深入的研究python中。

我要讲的是如何在程序中使用wxPython库,其中包括各种widget的获得,动态的切换widget,也有很多资料的,我就把我使用过程中觉得需要注意的总结一下,其中也说明了整个gui的构建框架

我把程序分成了三个文件
一个 main.py
一个 ui.py
一个 common.py

Main.py 是这样写的

import ui

if __name__ == '__main__':
application = ui.Application(0)
application.MainLoop()
else:
print "Can't import Buildipsl main module,it shoud be run alone!"

也就是在主程序中运行起来图形界面,进入事件循环,比较简单。

Ui.py程序比较长,大概有1000行,就不贴在这了,我主要说明的就是这个部分。

Common.py是一些常用的公共函数,定义的一些存放数据的底层的类,ui界面的数据交互最终都是通过和底层类对象数据交换来实现的,这样层次比较分明,也容易独立修改。

下面看一下ui.py文件中的Application类,也就是main.py中调用的那个类

class Application(wx.App):
def OnInit(self):
self.conf = common.HandleConfig('fic.conf')
self.connection_pool = common.ConnectionPool()
self.resource = xrc.XmlResource('../resource/IPSLBuild.xrc')
self.frame = MainFrame(None, self.resource,self.conf,self.connection_pool)
self.frame.Show()
return True

这个类在构造函数中实列化了一个’配置文件’类对象,一个’连接缓冲池’类对象,并且初始化了一个xrc资源文件类对象,传入MainFrame这个主窗体类。


MainFrame类 ,主窗体的实现类:
先看一下前几行
class MainFrame(wx.Frame):
def __init__(self, parent, resource,setting,pool):
self.res = resource
self.setting = setting
self.connection_pool=pool
self.PostCreate(self.res.LoadFrame(parent, 'MainWindow'))

self.PostCreate(self.res.LoadFrame(parent, 'MainWindow'))
这一行利用xrc资源对象,把在xml文件中定义的窗体load进来,设置本窗体类。

主窗体load进来了,接着就load窗体上的widget
一般的widget都可以使用像下面这样的函数:
self.text_ctrl_build_dir = xrc.XRCCTRL(self,'text_ctrl_build_dir')
也就是使用xrc,XRCCTRL,第一个参数是parent,这里是self,也就是我们load进来的主窗体,后面加的是包含在主窗体里的 widget的XML id 值,这样widget就进来了,由前面的self.text_ctrl_build_dir来引用着。使用和用代码构建出来的widget没什么区别。
但是,这里有例外,xrc.XRCCTRL只能使用在由wxWindow继承出来的widget上,如果widget不是由wxWindow 继承而来的,就获得不到对象引用,比如menu 和 toolbar。Menuitem和toolbar button要使用下面的方式:

Menubar:
self.menubar = self.res.LoadMenuBar('MainWindow_MenuBar')
这里的menubar在XML文件中是个顶层的widget,也就是说这个menubar不是包含在主窗体里的,结构上是和主窗体平级的

一个小提示:
XML文件中顶层的widget都是用LoadXXXX 来获得,非顶层的才使用XRCCTRL,并且XRCCTRL中第一个参数要是以LoadXXXX获得的widget做为直接或间接的父widget.
比如一个panel,如果在XML文件的最顶层,就要使用LoadPanel,如果在一个Frame中,那就要使用XRCCTRL(Frame的引用,’panel xml id’)

Menubar获得了,就把menubar设置在主窗体上
self.SetMenuBar(self.menubar)

获得子菜单用
self.menu_add = self.menubar.FindItemById(xrc.XRCID('menu_item_node_add'))

toolbar可以在主窗体上获得
self.toolbar = xrc.XRCCTRL(self,'MainWdinow_ToolBar')

在使用上,我获得toolbar button主要是要改变其可用和不可用的状态:
self.toolbar.EnableTool(xrc.XRCID("tool_button_node_add"),True)
想要toolbar button不能使用就用False
回调函数我下面再说.

到现在获得widget大家应该都没什么疑惑了吧,再说回调函数
回调函数一般是这样
self.config_panel.Bind(wx.EVT_BUTTON,self.OnConfSearch,id=xrc.XRCID('button_search_node_conf'))

self.Bind(wx.EVT_MENU, self.OnAdd,id=xrc.XRCID('menu_item_node_add'))
self.Bind(wx.EVT_TOOL, self.OnAdd,id=xrc.XRCID('tool_button_node_add'))

第一个是正常的Buttton
第二个是menuitem
第三个是toolbar button
其实都是一样的
父widget.Bind(事件类型,函数名,xml id)
再次说一下上面的menuitem 和toolbar button,其实如果不要像我这样要设置他们的可用和不可用的状态,不用获得他们的对象引用,可以直接绑定的,因为他们用的是xml id来查找的,没有bind在他们对象的引用上.

下面说一个我使用中的需求:
我窗体左边有一个treeview,需要在点左边不同的treeview item的时候,右边可以根据不同的情况变化.
我不想给右边通过代码来实现,因为可能有如下问题
1. 右边可能是个比较复杂的panel,代码量比较大,而且手写代码不容易后来的修改
2. 每次切换都要destory和Create一堆东西,资源的占用比较大
我喜欢完全的界面代码分离,好处多多,所以还是想用xrc的方式来做.
下面是实现步骤

右面我们要操作的实际上是一个splitter window的panel,叫splitter_right_panel

定义一个BoxSizer,用来向里面添东西
self.splitter_right_box_for_guest_panel=wx.BoxSizer(wx.VERTICAL)

初始化的时候先放上一个空panel
self.splitter_right_box_for_guest_panel.Add(wx.Panel(self),1, wx.EXPAND, 0)

设置布局
self.splitter_right_panel.SetAutoLayout(True)

设置容器
self.splitter_right_panel.SetSizer(self.splitter_right_box_for_guest_panel)

调整widget间的布局关系
self.splitter_right_box_for_guest_panel.Fit(self.splitter_right_panel)

把两个要加的panel都变成右边splitter_right_panel的子widget
self.config_panel.Reparent(self.splitter_right_panel)
self.connection_panel.Reparent(self.splitter_right_panel
这一步比较重要,一定要让panel的父widget是他的直接panel,如果是主窗体,显示有问题.
还有这两个panel是xml文件中顶层的panel,要使用LoadPanel加载进来.

初始化基本上就完成了,在切换中的代码是写在treeview中的select changed回调函数中.

self.main_frame.splitter_right_box_for_guest_panel.Detach(0)
self.main_frame.config_panel.Hide()
self.main_frame.connection_panel.Hide()

if ……:
self.main_frame.config_panel.Show()
self.main_frame.splitter_right_box_for_guest_panel.Add(self.main_frame.config_panel,1,wx.EXPAND,0)
else:
self.main_frame.connection_panel.Show()
self.main_frame.splitter_right_box_for_guest_panel.Add(self.main_frame.connection_panel,1,wx.EXPAND,0)


1. 任何时候都先把BoxSizer中的panel分离
2. 两个面板都hide
3. 根据判断加载不同的panel,show出来
这里用到的是Detach(),不要用Destory,panel对象是在xrc 资源文件中的,destory有问题,而且我们就是不想让它被destory,这样最开始得到的panel内部的widget的对象的引用一直都是可用的.

基本的原理我就说完了,写了两个common文件的类在这,是实现ssh连接的,我测试是可用的,还没写好, python异常我还没看,不好意思
使用的是paramiko模块,不过我用起来发现有问题,put和get函数有问题,没办法我自己写的put和get.
远程执行命令的时候不等执行完就退出了,命令在后台执行,这个不是我想要的,不过肯定有方法,只是我还不知道.我还没写完,让大家见笑了,呵呵

class Connection:
def __init__(self,ip,account,pwd):
self.trans = paramiko.Transport((ip, 22))
self.trans.connect(username=account, password=pwd)
def put(self,localfile,remotefile):
sftp=paramiko.SFTPClient.from_transport(self.trans)
data = open(localfile, 'r').read()
print 'remotefile is %s' % remotefile
sftp.open(remotefile, 'w').write(data)
def get(self,remotefile,localfile):
sftp=paramiko.SFTPClient.from_transport(self.trans)
data = sftp.open(remotefile, 'r').read()
open(localfile, 'w').write(data)
def execmd(self,cmd):
chan = self.trans.open_session()
chan.exec_command(cmd)
def active(self):
return self.trans.is_active()
def __del__(self):
self.trans.close()

class ConnectionPool:
def __init__(self):
self.pool={}
self.filelist=['bg','pnp','sub','fp','ep']
self.genscript='fic.pexpect'
def add_connection(self,name,ip,account,pwd):
if self.pool.has_key(name):
return False
try:
con=Connection(ip,account,pwd)
except Exception:
return False
self.pool[name]=con
return True
def del_connection(self,name):
if not self.pool.has_key(name):
return False
else:
del self.pool[name]
def connected(self,name):
if self.pool.has_key(name):
return True
else:
return False
def gen_config(self,name,path):
if not self.pool.has_key(name):
return False
try:
self.pool[name].execmd(r'rm -rf /tmp/%s' % self.genscript)
self.pool[name].put(get_path(self.genscript),'/tmp/%s' % self.genscript)
self.pool[name].execmd('python /tmp/%s' % self.genscript)
self.pool[name].execmd(r'rm -rf /tmp/%s' % self.genscript)
time.sleep(600)
for i in self.filelist:
print os.path.join(path,i)
self.pool[name].get("/tmp/fic/%s" % i,os.path.join(path,i))
except:
return False
return True

http://bbs.chinaunix.net/viewthread.php?tid=858243

标签: , ,

星期二, 八月 19, 2008

中文关键字提取

最近整的是中文分词与关键字提取,用python写的原型,算是复杂度比较可观的应用了;
分词的资料不太好找,只有KaiFu Lee在MSRA带着Guo姓小弟做的一些列paper和中科院I3S组的分词程序。
关键字提取是无先验信息的,篇幅也很短效,但是功能还是满意了。基本流程是聚类后,算条件概率,思想来自某大学的Paper。
起初的实现的模型,大概在1000汉字每秒的处理能力;
折腾了一天,提升到12000汉子每秒。
http://entelechie.ycool.com/post.2763166.html

标签: ,

基于Sphinx+MySQL的千万级数据全文检索(搜索引擎)架构设计

http://blog.s135.com/read.php/360.htm

[文章作者:张宴 本文版本:v1.0 最后修改:2008.07.27 转载请注明原文链接:http://blog.s135.com/read.php/360.htm]

  前言:本文阐述的是一款经过生产环境检验的千万级数据全文检索(搜索引擎)架构。本文只列出前几章的内容节选,不提供全文内容。

   在DELL PowerEdge 6850服务器(四颗64 位Inter Xeon MP 7110N处理器 / 8GB内存)、RedHat AS4 Linux操作系统、MySQL 5.1.26、MyISAM存储引擎、key_buffer=1024M环境下实测,单表1000万条记录的数据量(这张MySQL表拥有int、 datetime、varchar、text等类型的10多个字段,只有主键,无其它索引),用主键(PRIMARY KEY)作为WHERE条件进行SQL查询,速度非常之快,只耗费0.01秒。

  出自俄罗斯的开源全文搜索引擎软件Sphinx, 单一索引最大可包含1亿条记录,在1千万条记录情况下的查询速度为0.x秒(毫秒级)。Sphinx创建索引的速度为:创建100万条记录的索引只需 3~4分钟,创建1000万条记录的索引可以在50分钟内完成,而只包含最新10万条记录的增量索引,重建一次只需几十秒。

  基于以上 几点,我设计出了这套搜索引擎架构。在生产环境运行了一周,效果非常不错。有时间我会专为配合Sphinx搜索引擎,开发一个逻辑简单、速度快、占用内存 低、非表锁的MySQL存储引擎插件,用来代替MyISAM引擎,以解决MyISAM存储引擎在频繁更新操作时的锁表延迟问题。另外,分布式搜索技术上已 无任何问题。

全部内容请点击上面链接

标签: , , ,

有用的Python中文分词链接

python中文分词模块

http://www.zeuux.org/pipermail/zeuux-python/2007-June/039597.html


分词后续, SCWS(简体中文分词)第4版出来了 :-)

http://www.chmhome.com/knowledge/php/20070624/50559.html

中文分词
http://nzinfo.spaces.live.com/?_c11_BlogPart_BlogPart=blogview&_c=BlogPart&partqs=cat%3D%25e4%25b8%25ad%25e6%2596%2587%25e5%2588%2586%25e8%25af%258d

中文分词
http://www.162cm.com/archives/tag/%E4%B8%AD%E6%96%87%E5%88%86%E8%AF%8D

标签: ,

中文分词Python相关

中文搜索/分词

http://wiki.woodpecker.org.cn/moin/PyInChinese

标签: ,

星期四, 八月 14, 2008

Google App Engine 提供5G Python空间

Google App Engine是Google推出的免费虚拟主机空间,其实这比一般虚拟主机强悍的多,你可以利用Google App Engine工具来开发网站或制作网络应用程序,Google会在自己的庞大服务器集群上为你提供空间、带宽、资源等。目前Google App Engine为每个用户提供10个Application(简称App),每个App有500M免费空间,每个App限制1000个文件,单个文件1M以 内,每天流量20G。每个App提供免费二级域名1个,同时也可绑米。目前还仅支持Python一种语言脚本,不支持PHP、Perl、ASP等。

注意:这是Google面向程序开发人员提供的一项免费服务,如果你对Python不了解也不感兴趣建议不要申请,虽然很强悍但使用起来比任何一个免费空间都麻烦。

网址:http://appengine.google.com

如果你使用Google Apps,可以用“http://appengine.google.com/a/你的域名/”这个地址来申请,如果你要绑定域名,仅能绑定申请了 Google Apps服务的域名。另外,申请的时候需要填写手机号码,会给你发送确认码来确认申请,目前Google在中国仅支持中国联通,所以要用联通手机申请才能 收到确认码,如果你用的不是联通手机,那就无缘Google App Engine了,且一个手机只能申请一个帐户。

官方入门指南:http://code.google.com/appengine/docs/gettingstarted

入门指南中文翻译版:http://hi.baidu.com/…/772eb07e43ff613d0cd7daa6.html

目前官方仅有英文版入门指南,所以在网上找了个网友翻译的中文版给大家做参考,有兴趣仔细看看吧。

配额限制:http://code.google.com/appengine/articles/quotas.html

Google App Engine详细配额限制,很全面。你的程序上传运行后,在Google App Engine的管理面板中可以看到配额使用情况。

Python运行限制:http://code.google.com/appengine/docs/python

Google App Engine中的Python是运行在一个受限的环境中,例如:对操作系统的底层调用、网络操作以及一些文件系统操作都是不允许的,尝试这些操作时会引起错误。

演示:http://free8.appspot.com

费了好大劲才弄好了一个页面,对于Python不太了解的新手来说,建议不要申请使用。
另外给大家两个用Google App Engine做的在线代理网站演示:

http://w3w.appspot.com

http://go2.appspot.com

原文:http://www.chinaz.com/Webbiz/Free/0PS4Z02008.html

标签: ,

星期四, 七月 24, 2008

XRC方式载入的wxPython对象访问方式

res = xrc.XmlResource(’resource.xrc’)
res.LoadPanel(self, ‘MyPanel’)

self.Bind(wx.EVT_BUTTON, self.OnClose, id=xrc.XRCID(’CloseButton’))
self.Center()

标签: , , ,

星期三, 七月 16, 2008

wxPython之XRC加载流水账.2

用下面的代码,执行结果是正确的。不知道为什么,如果有StatusBar,总会少一点,resize之后正常。

#-*- coding: utf-8 -*-

import wx
import wx.xrc as xrc

class MyApp(wx.App):
def OnInit(self):
self.res = xrc.XmlResource(r'./cr01.xrc')
self.frame_1 = self.res.LoadFrame(None, 'MyFrame2')
self.frame_1.Show(True)
return 1

if '__main__' == __name__:
app = MyApp()
app.MainLoop()

重要的参考文件 :
wxPython中XRC文件i18n示例

标签: , ,

wxPython之XRC加载流水账

按图索骥一番,用以下代码测试一下:

#!/usr/bin/python
#-*- coding: utf-8 -*-

import wx
import wx.xrc as xrc

class XML(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title)

res = xrc.XmlResource('cr01.xrc')
res.LoadFrame(self, 'MyFrame2')

self.Center()
self.Show(True)

def OnClose(self, event):
self.Close()

app = wx.App()
XML(None, -1, 'xml resource test')
app.MainLoop()

cr01.xrc里定义了数个组件,发现载入进来的只是一个空框架。

参考文件 :http://privacybrowse.info/index.php?hl=f5&q=uggc%3A%2F%2Fzejyjna.jbeqcerff.pbz%2F2008%2F05%2F03%2Fjkclguba%25RS%25OP%259Nkep%2F

标签: , ,

星期二, 七月 15, 2008

Python in Action中文翻译

项目地址:
http://www.mangbar.com/task/doclist/5d023b211427315f01142a6590000324

标签:

星期三, 七月 09, 2008

竽充数:Python抓网页内容的两个sample程序

Python是Google公司最重要的三大开发语言之一(C++, Java, Python)

用Python语言写搜索引擎蜘蛛的脚本非常简单、轻松。给大家分享两种抓网页内容的方法

一、用urllib2/sgmllib包,将目标网页的所有URL列出。

import urllib2

from sgmllib import SGMLParser

class URLLister(SGMLParser):
def reset(self):
SGMLParser.reset(self)
self.urls = []

def start_a(self, attrs):
href = [v for k, v in attrs if k=='href']
if href:
self.urls.extend(href)

f = urllib2.urlopen("http://www.donews.com")

if f.code == 200:
parser = URLLister()
parser.feed(f.read())
f.close()
for url in parser.urls: print url

二、用python调用IE抓取目标网页(Require win32com, pythoncom)的所有图像的url和大小

import win32com.client, pythoncom
import time

ie = win32com.client.DispatchEx('InternetExplorer.Application.1')
ie.Visible = 1
ie.Navigate("http://news.sina.com.cn")
while ie.Busy:
time.sleep(0.05)

doc = ie.Document
for i in doc.images:
print i.src, i.width, i.height

这种方法可以利用IE本身的Javascript. DHTML的支持,来做自动提交Form,和处理Javascript。
有关样例可以参考http://win32com.de

http://blog.donews.com/dengyu/archive/2005/11/09/620119.aspx

标签: , ,

用python解析html

http://rurutia.is-programmer.com/show/100.html

标签: , ,

星期四, 六月 26, 2008

[Python]用 Python 实现的线程池

为了提高程序的效率,经常要用到多线程,尤其是IO等需要等待外部响应的部分。线程的创建、销毁和调度本身是有代价的,如果一个线程的任务相对简 单,那这些时间和空间开销就不容忽视了,此时用线程池就是更好的选择,即创建一些线程然后反复利用它们,而不是在完成单个任务后就结束。

下面是用Python实现的通用的线程池代码:

  1. import Queue, threading, sys
  2. from threading import Thread
  3. import time,urllib
  4. # working thread
  5. class Worker(Thread):
  6. worker_count = 0
  7. def __init__( self, workQueue, resultQueue, timeout = 0, **kwds):
  8. Thread.__init__( self, **kwds )
  9. self.id = Worker.worker_count
  10. Worker.worker_count += 1
  11. self.setDaemon( True )
  12. self.workQueue = workQueue
  13. self.resultQueue = resultQueue
  14. self.timeout = timeout
  15. def run( self ):
  16. ''' the get-some-work, do-some-work main loop of worker threads '''
  17. while True:
  18. try:
  19. callable, args, kwds = self.workQueue.get(timeout=self.timeout)
  20. res = callable(*args, **kwds)
  21. print "worker[%2d]: %s" % (self.id, str(res) )
  22. self.resultQueue.put( res )
  23. except Queue.Empty:
  24. break
  25. except :
  26. print 'worker[%2d]' % self.id, sys.exc_info()[:2]
  27. class WorkerManager:
  28. def __init__( self, num_of_workers=10, timeout = 1):
  29. self.workQueue = Queue.Queue()
  30. self.resultQueue = Queue.Queue()
  31. self.workers = []
  32. self.timeout = timeout
  33. self._recruitThreads( num_of_workers )
  34. def _recruitThreads( self, num_of_workers ):
  35. for i in range( num_of_workers ):
  36. worker = Worker( self.workQueue, self.resultQueue, self.timeout )
  37. self.workers.append(worker)
  38. def start(self):
  39. for w in self.workers:
  40. w.start()
  41. def wait_for_complete( self):
  42. # ...then, wait for each of them to terminate:
  43. while len(self.workers):
  44. worker = self.workers.pop()
  45. worker.join( )
  46. if worker.isAlive() and not self.workQueue.empty():
  47. self.workers.append( worker )
  48. print "All jobs are are completed."
  49. def add_job( self, callable, *args, **kwds ):
  50. self.workQueue.put( (callable, args, kwds) )
  51. def get_result( self, *args, **kwds ):
  52. return self.resultQueue.get( *args, **kwds )

Worker类是一个工作线程,不断地从workQueue队列中获取需要执行的任务,执行之,并将结果写入到resultQueue中,这里的 workQueue和resultQueue都是现成安全的,其内部对各个线程的操作做了互斥。当从workQueue中获取任务超时,则线程结束。

WorkerManager负责初始化Worker线程,提供将任务加入队列和获取结果的接口,并能等待所有任务完成。

一个典型的测试例子如下,它用10个线程去下载一个固定页面的内容,实际应用时应该是执行不同的任务。

  1. def test_job(id, sleep = 0.001 ):
  2. try:
  3. urllib.urlopen('https://www.gmail.com/').read()
  4. except:
  5. print '[%4d]' % id, sys.exc_info()[:2]
  6. return id
  7. def test():
  8. import socket
  9. socket.setdefaulttimeout(10)
  10. print 'start testing'
  11. wm = WorkerManager(10)
  12. for i in range(500):
  13. wm.add_job( test_job, i, i*0.001 )
  14. wm.start()
  15. wm.wait_for_complete()
  16. print 'end testing'

完成的程序可以在这里下载

http://blogger.org.cn/blog/more.asp?name=lhwork&id=22262

标签: ,

星期五, 六月 20, 2008

如何使用wxPython设计gui

wxPython介绍+一个实用的例子

1. wxPython简介

wxPython是wxWidget的库的一个python的封装。提供了一些库和一些工具。

这样wxPython即有python语言的优点:
语法强悍,少写了不少代码:)

也有wxWidget图形库的优点:
直接拉控件到大概位置就行了,不需要去调整控件的对齐,也不需要关心gui界面是否支持各种分辨率的桌面。而且界面都是可以运行时切换,只要写很少的切换代码。跨平台的图形库...

后悔,我怎么以前会用vb开发gui的 -_-!。

缺点,网上资料还比较少。而且在线文档都是英文的。不过如果英文好的话,到真的无所谓,因为wxPython的安装包本身提供的工具和资料也足够多,足够好了。

2. 开发入门
我使用ultraedit作为编辑器,wxPython自带的XRCed作为编辑xrc文件(一种xml格式的资源文件,类似于VC6中的RC文件)。

文档主要参考wxPython自带的在线文档和demo代码。不过关于如何使用xrc文件设计gui,wxPython自带的资料似乎还不够详细,这也是我写本文的原因。

通常情况下google"cvs def wxpython相关的关键字"可以快速找到开源的源代码参考。

如果这些例子还不够的话,就参考我的程序吧,这是一个商用程序的原型,我相信该程序的内容已经足够丰富了,应该比网上的一些wxPython教程中的hello world程序更有借鉴意义。

3. 源代码
两个文件,main.py是主程序,main.xrc是资源文件。只要安装了了python和wxpython,然后将这两个文件放在同一个目录中,运行main.py就可以了。

http://www.builder.com.cn/2008/0527/887121.shtml

很重要,此文的实现基于.xrc文件。

标签: , ,

wxpython:sizer学习

使用sizer后,mainFrame的大小由sizer的孩子决定

grid sizer:

最简单的一个种sizer,各个栅的大小相同,栅的最大大小取决以栅中最大孩子的尺寸(当一个sizer被创建时,它根据它的孩子的综合的最小尺寸(最小的宽度和最小的高度)隐含地创建一个最小尺寸。),如果一个栅没有孩子,不会占有效空间的.gridsizer不会限制孩子的个数的,即使在开始声明也是一样

=========================

flex grid sizer

默认情况下,当尺寸调整时,它不改变它的单元格的尺寸。

可以指定某方向上的行为(以行或列为其它单位,gridsizer是以整体为单位),每个栅的宽度是该列中宽度最大的项目的宽度,它们的高度是该行中宽度最高的项目的宽度。显式地告诉该sizer该行或列是可扩展的:

当窗体大小变化时,需要显式地告诉该sizer该行或列是可扩展的:
AddGrowableCol(idx, proportion=0)
AddGrowableRow(idx, proportion=0)

SetFlexibleDirection(direction)

SetNonFlexibleGrowMode(mode)

=========================
grid bag sizer

1、能够将一个窗口部件添加到一个特定的单元格。(如果一个栅没有孩子,会占有效空间的)
2、能够使一个窗口部件跨越几个单元格(就像HTML表单中的表格所能做的一样)。

注意这里的Add()方法与以前的看起来有点不同 :

1 Add(window, pos, span=wx.DefaultSpan, flag=0, border=0, userData=None)

2 Add(sizer, pos, span=wx.DefaultSpan, flag=0, border=0, userData=None)

3 Add(size, pos, span=wx.DefaultSpan, flag=0, border=0, userData=None)

4 AddItem(item)
比其它sizer多了一个位置参数:因为它为孩子预留了空间

============== 下面是通用方法 ================

sizer对象的构造方法有两个比较重要的参数:

flag:窗体风格,对齐方式,边框位置

proportion:如果使用窗体大小变化时的空间使用,为一个比例值

孩子指定一个最小的尺寸

窗口的方法

SetMinSize(width, height)

SetSizeHints(minW, minH, maxW, maxH)

使用sizer的SetItemMinSize()方法。它也有三个形式:

SetItemMinSize(window, size)
SetItemMinSize(sizer, size)
SetItemMinSize(index, size)

对sizer添加或移除孩子:

Add(window, proportion=0, flag=0, border=0, userData=None)
Add(sizer, proportion=0, flag=0, border=0, userData=None)
Add(size, proportion=0, flag=0, border=0, userData=None)

Insert(index, window, proportion=0, flag=0, border=0, userData=None)
Insert(index, sizer, proportion=0, flag=0, border=0, userData=None)
Insert(index, size, proportion=0, flag=0, border=0, userData=None)

Prepend(window, proportion=0, flag=0, border=0, userData=None)
Prepend(sizer, proportion=0, flag=0, border=0, userData=None)
Prepend(size, proportion=0, flag=0, border=0, userData=None)

Detach(window)
Detach(sizer)
Detach(index)

管理它的孩子的尺寸和对齐的

调整grid sizer的大小时,每个部件之间的间隙将随之改变,但是默认情况下,窗口部件的尺寸不会变,并且始终按左上角依次排列

添加一个窗口部件到sizer时,可以通过给flag参数一个特定值来调整该窗口部件的尺寸改变行为。
wx.ALIGN_BOTTOM:按照窗口部件被分配的空间(格子)的底部对齐。

wx.ALIGN_CENTER:放置窗口部件,使窗口部件的中心处于其所分配的空间的中心。

wx.ALIGN_CENTER_HORIZONTAL:在它所处的格子中,水平居中。

wx.ALIGN_CENTER_VERTICAL :在它所处的格子中,垂直居中。

wx.ALIGN_LEFT:靠着它所处的格子左边缘。这是默认行为。

wx.ALIGN_TOP:靠着它所处的格子的上边缘。这是默认的行为。

wx.EXPAND:填满它所处的格子空间。

wx.FIXED_MINSIZE:保持固定项的最小尺寸。

wx.GROW:与wx.EXPAND相同。但比之少两个字符,节约了时间。

wx.SHAPED:窗口部件的尺寸改变时,只在一个方向上填满格子,另一个方向上按窗口部件原先的形状尺寸的比列填充。什么方向的sizer就向什么方向增长

管理每个孩子的边框

边框是连续数量的空白空间,方向有:wx.BOTTOM, wx.LEFT, wx.RIGHT, wx.TOP

传递了边框信息到flags参数后,也需要传递边框宽度的像素值给border参数 ,为边框的大小

http://sellroad.w58.ws86.com/jessinio/?p=512

标签: , , ,

Python中向MySQL保存Blob

Python code
import MySQLdb, cPickle
# Connect to a DB, e.g., the test DB on your localhost, and get a cursor
connection = MySQLdb.connect(db="test")
cursor
= connection.cursor( )
# Make a new table for experimentation
cursor.execute("CREATE TABLE justatest (name TEXT, ablob BLOB)")
try:
# Prepare some BLOBs to insert in the table
names = 'aramis', 'athos', 'porthos'
data
= { }
for name in names:
datum
= list(name)
datum.sort( )
data[name]
= cPickle.dumps(datum, 2)
# Perform the insertions
sql = "INSERT INTO justatest VALUES(%s, %s)"
for name in names:
cursor.execute(sql, (name, MySQLdb.escape_string(data[name])) )
# Recover the data so you can check back
sql = "SELECT name, ablob FROM justatest ORDER BY name"
cursor.execute(sql)
for name, blob in cursor.fetchall( ):
print name, cPickle.loads(blob), cPickle.loads(data[name])
finally:
# Done. Remove the table and close the connection.
cursor.execute("DROP TABLE justatest")
connection.close( )
http://topic.csdn.net/u/20080319/11/814acdd6-a064-4419-ae52-930cdc97ca45.html

标签: , ,

A PYTHON APPLICATION WHERE THREADS WOULD HELP

Let's say that you want to check the availability of many computers on a network ... you'll use ping. But there's a problem - if you "ping" a host that's not running it takes a while to timeout, so that when you check through a whole lot of systems that aren't responding - the very time a quick response is probably needed - it can take an age.

Here's a Python program that "ping"s 10 hosts in sequence.

import os
import re
import time
import sys

lifeline = re.compile(r"(\d) received")
report = ("No response","Partial Response","Alive")

print time.ctime()

for host in range(60,70):
ip = "192.168.200."+str(host)
pingaling = os.popen("ping -q -c2 "+ip,"r")
print "Testing ",ip,
sys.stdout.flush()
while 1:
line = pingaling.readline()
if not line: break
igot = re.findall(lifeline,line)
if igot:
print report[int(igot[0])]

print time.ctime()

Running that program, it works but it's a bit slow:

[trainee@buttercup trainee]$ python alive
Mon May 9 05:22:51 2005
Testing 192.168.200.60 No response
Testing 192.168.200.61 No response
Testing 192.168.200.62 No response
Testing 192.168.200.63 No response
Testing 192.168.200.64 No response
Testing 192.168.200.65 No response
Testing 192.168.200.66 Alive
Testing 192.168.200.67 No response
Testing 192.168.200.68 No response
Testing 192.168.200.69 No response
Mon May 9 05:23:19 2005
[trainee@buttercup trainee]$

That was 28 seconds - in other words, an extra 3 seconds per unavailable host.

THE SAME APPLICATION, WRITTEN USING PYTHON THREADS

I'll write the application and test it first ... then add a few notes at the bottom.

import os
import re
import time
import sys
from threading import Thread

class testit(Thread):
def __init__ (self,ip):
Thread.__init__(self)
self.ip = ip
self.status = -1
def run(self):
pingaling = os.popen("ping -q -c2 "+self.ip,"r")
while 1:
line = pingaling.readline()
if not line: break
igot = re.findall(testit.lifeline,line)
if igot:
self.status = int(igot[0])

testit.lifeline = re.compile(r"(\d) received")
report = ("No response","Partial Response","Alive")

print time.ctime()

pinglist = []

for host in range(60,70):
ip = "192.168.200."+str(host)
current = testit(ip)
pinglist.append(current)
current.start()

for pingle in pinglist:
pingle.join()
print "Status from ",pingle.ip,"is",report[pingle.status]

print time.ctime()

And running:

[trainee@buttercup trainee]$ python kicking
Mon May 9 05:23:36 2005
Status from 192.168.200.60 is No response
Status from 192.168.200.61 is No response
Status from 192.168.200.62 is No response
Status from 192.168.200.63 is No response
Status from 192.168.200.64 is No response
Status from 192.168.200.65 is No response
Status from 192.168.200.66 is Alive
Status from 192.168.200.67 is No response
Status from 192.168.200.68 is No response
Status from 192.168.200.69 is No response
Mon May 9 05:23:39 2005
[trainee@buttercup trainee]$

3 seconds - much more acceptable than the 28 seconds that we got when we pinged the hosts one by one and waited on each.

http://www.wellho.net/solutions/python-python-threads-a-first-example.html

标签: ,

python中的编码转换

ASCII 是一种字符集,包括大小写的英文字母、数字、控制字符等,它用一个字节表示,范围是 0-127

Unicode分为UTF-8和UTF-16。UTF-8变长度的,最多 6 个字节,小于 127 的字符用一个字节表示,与 ASCII 字符集的结果一样,ASCII 编码下的英语文本不需要修改就可以当作 UTF-8 编码进行处理。

Python 从 2.2 开始支持 Unicode ,函数 decode( char_set )可以实现 其它编码到 Unicode 的转换函数 encode( char_set )实现 Unicode 到其它编码方式的转换

比如 ("你好").decode( "GB2312") 将得到 u'\u4f60\u597d',即 "你"和“好"的 Unicode 码分别是 0x4f60 和 0x597d
再用 (u'\u4f60\u597d').encode("UTF-8") 将得到 '\xe4\xbd\xa0\xe5\xa5\xbd',它是 “你好”的UTF-8编码结果。


python中使用 unicode的关键:unicode是一个类,函数unicode(str,"utf8")从utf8编码(当然也可以是别的编码)的字符串str生成 unicode类的对象,而函数unc.encode("utf8")将unicode类的对象unc转换为(编码为)utf8编码(当然也可以是别的编码)的字符串。于是,编写unicode相关程序,需要做的事情是

* 获取数据(字符串)时,用unicode(str, "utf8")生成unicode对象
* 在程序中仅使用unicode对象,对程序中出现的字符串常量都以u"字符串"的形式书写
* 输出时,可将unicode对象转换为任意编码输出,使用str.encode("some_encoding")

>>> unicode("你好", "utf8")
u'\u4f60\u597d'
>>> x = _
>>> type(x)

>>> type("你好")

>>> x.encode("utf8")
'\xe4\xbd\xa0\xe5\xa5\xbd'
>>> x.encode("gbk")
'\xc4\xe3\xba\xc3'
>>> x.encode("gb2312")
'\xc4\xe3\xba\xc3'
>>> print x
你好
>>> print x.encode("utf8")
你好
>>> print x.encode("gbk")
???

以上是测试结果(Ubuntu 6.06,locale为utf8),注意type(x)和type("你好")的区别。从编码上可以看出utf8编码与gbk不同。在utf8的 locale设置下,打印x按该环境变量编码(我猜我猜我猜猜猜),而打印x.encode("gbk")则是乱码。
http://guanjh.javaeye.com/blog/131185

标签: , , ,

星期五, 六月 13, 2008

Python扩展方法及工具比较

一、普通扩展方法
扩展Python包括三个步骤:
1. 创建源程序(C, C++, java, ...);
2. 为源程序写wrap代码;
包括四个步骤:
Ø include "Python.h";
Ø 为每个模块函数写wrap,即:PyObject* Module_func();
Ø 为每个模块函数写函数定义,即:PyMethodDef ModuleMethods[]对应表;
Ø 写模块的初始化函数:void initModule()部分。
3. 编译连接;
有两种方法:
(1)使用distutils包。步骤如下:
Ø 修改distutils包中的setup.py文件;
Ø 根据需要运行$ python setup.py build或$ python setup.py install命令,生成扩展
模块的共享库文件。
(2)直接使用gcc命令将模块编译成共享库。命令如下:
$ gcc -fpic -c -I/usr/include/python2.2 -I/usr/lib/python2.2/config foo.c
wrap_foo.c
$ gcc -shared -o foo.so foo.o wrap_foo.o
这样便生成了python可用的foo模块。
4. 使用扩展内容
进入python环境,通过import foo,使用foo模块中的函数。如用foo.func()调用foo模
块中的func()函数。

http://hi.baidu.com/minyuanyang/blog/item/1222c5c831075a137e3e6f0a.html

标签: ,

星期五, 六月 06, 2008

Compiling Python Code

Python source code is automatically compiled into Python byte code by the CPython interpreter. Compiled code is usually stored in PYC (or PYO) files, and is regenerated when the source is updated, or when otherwise necessary.

To distribute a program to people who already have Python installed, you can ship either the PY files or the PYC files. In recent versions, you can also create a ZIP archive containing PY or PYC files, and use a small “bootstrap script” to add that ZIP archive to the path.

To “compile” a Python program into an executable, use a bundling tool, such as Gordon McMillan’s installer (alternative download) (cross-platform), Thomas Heller’s py2exe (Windows), Anthony Tuininga’s cx_Freeze (cross-platform), or Bob Ippolito’s py2app (Mac). These tools puts your modules and data files in some kind of archive file, and creates an executable that automatically sets things up so that modules are imported from that archive. Some tools can embed the archive in the executable itself.

If all you need is to wrap up a couple of Python scripts and modules into a single file, Squeeze might be what you need. For Windows, my ExeMaker tool can also be quite useful (on its own, or in combination with squeeze).

Compiling Python modules to byte code #

Python automatically compiles Python source code when you import a module, so the easiest way to create a PYC file is to import it. If you have a module mymodule.py, just do:

>>> import mymodule

to create a mymodule.pyc file in the same directory. A drawback is that it doesn’t only compile the module, it also executes it, which may not be what you want. (however, it does compile the entire script even if it fails to execute the script).

To do this programmatically, and without executing the code, you can use the py_compile module:

import py_compile

py_compile.compile("mymodule.py")

There’s also a compileall module which can be used to compile all modules in an entire directory tree.

import compileall

compileall.compile_dir("mylib", force=1)

More on byte code #

Python’s byte code is portable between platforms, but not necessarily between Python releases. The imp.get_magic() function returns a 4-byte string identifying the byte code format used by the current interpreter.

You can use the compile function and the marshal module to compile Python code into code objects, and convert such code objects to binary strings. To reverse this process, use marshal to convert from strings to code, and use exec to execute code.

Examples to be added.

http://effbot.org/zone/python-compile.htm

标签:

星期二, 六月 03, 2008

在pyLucene中使用中文分词器(在pyLucene中引用Jar包)

(刚刚解决的一个问题,在中文里面没有搜索到相关内容(英文里其实也没搜到...),发一篇在这里备人索引,关键字:pyLucene, JCC,
Lucene, Importing JAR)

在Lucene里面引用别人写好的中文分词器很简单,加个CLASSPATH就好。但是在pyLucene(JCC版)里,由于python所能够引用
到的Jar包都是用JCC这个编译器(姑且认为是个编译器吧)预先编译了python调用接口的。(反过来说,就是没有经JCC编译的Jar包是休想在
python里面直接访问的)

所以,在pyLucene中使用Jar包形式的中文分词器不得不重新编译。分隔线以下是OSFoundation某热心人关于如何修改Makefile
让Jar包可以和pyLucene打包到一起的回复。

-------------------------------------热心人回复的分隔
线-------------------------------------
Andi Vajda:
To access your class(es) by name from Python, you must have JCC
generate wrappers for it (them). This is what is done line 177 and on
in PyLucene's Makefile. The easiest way for you to add your own Java
classes to PyLucene is to create another jar file with your own
analyzer classes and code and add it to the JCC invocation there.

For example, the Makefile snippet in question currently says:

GENERATE=$(JCC) $(foreach jar,$(JARS),--jar $(jar)) \
--package java.lang java.lang.System \
java.lang.Runtime \
--package java.util \
java.text.SimpleDateFormat \
--package java.io java.io.StringReader \
java.io.InputStreamReader \
java.io.FileInputStream \
--exclude org.apache.lucene.queryParser.Token \
--exclude org.apache.lucene.queryParser.TokenMgrError \
--exclude
org.apache.lucene.queryParser.QueryParserTokenManager \
--exclude org.apache.lucene.queryParser.ParseException \
--python lucene \
--mapping org.apache.lucene.document.Document 'get:(Ljava/
lang/String;)Ljava/lang/String;' \
--mapping java.util.Properties 'getProperty:(Ljava/lang/
String;)Ljava/lang/String;' \
--sequence org.apache.lucene.search.Hits 'length:()I' 'doc:
(I)Lorg/apache/lucene/document/Document;' \
--version $(LUCENE_VER) \
--files $(NUM_FILES)

change the first line to say:

GENERATE=$(JCC) $(foreach jar,$(JARS),--jar $(jar)) --jar myjar.jar \
...

and rebuild PyLucene. That should be all you need to do. Your jar file
is going to be installed along with lucene's in the lucene egg and it
is going to be put on lucene.CLASSPATH which you use with
lucene.initVM().

Your classes can be declared in any Java package you want. Just make
sure that their names don't clash with other Lucene class names that
you also need to use as the class namespace is flattened in PyLucene.

For more information about JCC and its command line args see JCC's
README file at [1].

Andi..

[1] http://svn.osafoundation.org/pylucene/trunk/jcc/jcc/README
_______________________________________________
pylucene-dev mailing list
pylucene-...@osafoundation.org
http://lists.osafoundation.org/mailman/listinfo/pylucene-dev


http://groups.google.com.pe/group/python-cn/browse_thread/thread/0f085de0eab6f039

标签: , ,

Python下的Lucene,PyLucene

下一个项目准备用Python+Django来完成,先做些技术准备。数据库方面用Django已经 试验的差不多了,但是似乎性能很差。自己编译了Mysql,用虚拟机测试,生成1000个用户,1000篇文章用时80秒,这种并发性能恐怕没有办法让人 满意。(每篇文章需要单独生成Tag和文章与Tag的对应关系,涉及8次数据库操作。)花了一天时间试验InnoDB和MyIsam的区别,但是似乎没有 影响,开不开Transaction都一样。先不管它了,也许和我的机器硬件有关系,硬件的sync关不掉。看官方的说法,SlashDot用 Django可以实现每秒800条数据的插入速度。

网站肯定要用到全文检索,目前唯一的全文检索解决方案就是Lucene了,.Net上也有Lucene.Net可以选。搜索了一下,发现了PyLucene,这个Python上的Lucene实现。似乎是使用Python对Lucene进行了一次重新包装。

下 载了它的Windows版本,安装比较简单,直接把几个库文件复制到对应的Lib目录就行了。运行了一下Sample目录下的测试文件,先是用 IndexFiles和SearchFiles试了一下,SearchFiles是接收参数来搜索的,但是我没有办法输入中文,会出现错误提示。后来把要 搜索的词直接放到文件里面去,不报错了,但是搜索不出来。本以为PyLucene不支持中文,正在纳闷豆瓣的搜索是怎么做的,突然发现了一个好东西。

看 了一下sample目录下的LuceneInAction目录,里面居然有个ChineseTest文件。它调用的是另一个目录下的测试文件,测试一个汉 字的搜索,运行了一下,居然是成功的。再看了一下IndexFiles,里面读文件用的编码是英文编码,改成GB2312,OK,可以搜索到了。但是只能 搜索单字,不能按词搜索。只要输入两个字就出错。再比较一下Test文件,Query的生成方法不一样,TermQuery似乎是单元搜索,不支持词搜 索,换成了QueryParser,成功了。但是还有一个小问题,比如搜索“中华”,在文章里,在中和华中间随便加多少空格和回车都没有关系,照样可以搜 索到。但是加入其它字或者英文字母以后就搜索不到了。这个影响不大,毕竟人们常用的搜索都是自然词。

有了PyLucene这个好东西,心头一块大石头算是落地了。没想到,等到要在开发服务器的Linux上安装这个东西的时候,可费了功夫了。

官 方的下载包做的很奇怪,ubuntu, debian, gentoo都有对应的二进制包可用,但是Redhat就没有,只能用源码包编译,而它的编译方式又做的极其简陋,没有configure文件,只有 Makefile。按照说明,需要自己编辑Makefile,去掉你需要的注释行,修改参数,然后直接Make。但是里面有一个对DB的引用,检查了一 下,BerkeleyDB似乎在CentOS4里面没有,只好自己去官方网站下载了4.4.20的源码,先编译安装它。虽然最新版是4.5.20,但是怕 不兼容,所以还是用它配置文件里推荐的这个。编译这个东西也挺奇怪,不过还好,毕竟有官方文档一步步的说明,解压后需要进入build_unix目录,然 后调用../dist/configure来配置,然后make && make install。指定prefix失败。装完了这个东西,再改PyLucene的配置文件,根据生成的错误消息猜了好几次才终于可以编译了。最终需要改的 地方为:

1、取消Linux那一段的注释。

2、PREFIX_PYTHON是你的Python的目录。因为我的Python是自己编译安装的,所以这里需要改一下。

3、DB=这个我指向了BerkeleyDB的源码目录才通过编译的(还好没删)。

其 它的不用改。编译到一半报错,有一个libgcj.a文件找不到,到/usr/lib下找了一下没有这个文件,但是有个差不多的.so,于是做了个ln -s,居然就通过编译了。然后make install的时候又有问题,提示libgcc_s.so.1找不到,这个是Makefile里面的LIB_INSTALL参数指定的,我不知道它的意 义在哪里,最后我也没找到这个文件,但是直接进入Sample目录运行了一下测试文件,居然就成功了。真TMD。这就是Linux吗?

终于可以安心的研究Django了。似乎Ruby On Rails还没有支持中文全文检索的模块吧?

http://www.cnblogs.com/unfish/archive/2006/10/25/539956.html

标签: , ,

星期三, 五月 14, 2008

;)

C/C++还是最棒的

Object Pascal也不错,至少目前Free Pascal的发展比Delphi的命运好像好一点

Python易学易用,语法太灵活了,缩进还是没有;号爽

UML 2.0还没有达到易用,易懂的程度,也许以后描述问题不用它了吧

PHP做网站很不错,CodeIgniter框架也不错,就是对XHTML的支持,特别是UTF-8的支持不是很理想。

标签: , , , , , , ,

Reverse engineer MS Access/Jet databases

# jet2sql.py - M.Keranen  [07/12/2000]
# --------------------------------------------------------------------
# Creates ANSI SQL DDL from a MS Jet database file, useful for reverse
# engineering database designs in E/R tools.
#
# Requires DAO 3.6 library.
# --------------------------------------------------------------------
# Usage: python jet2sql.py infile.MDB outfile.SQL

import sys, string, pythoncom, win32com.client

const = win32com.client.constants
daoEngine = win32com.client.Dispatch('DAO.DBEngine.36')

class jetReverse:
def __init__ (self, infile):

self.jetfilename=infile
self.dtbs = daoEngine.OpenDatabase(infile)

return

def terminate(self):
return

def writeTable(self, currTabl):
self.writeLine('\ncreate table ' + chr(34) + currTabl.Name + chr(34),"",1)
self.writeLine('(',"",1)

# Write Columns
cn=0
for col in currTabl.Fields:
cn = cn +1
self.writeColumn(col.Name, col.Type, col.Size, col.Required, col.Attributes, col.DefaultValue, col.ValidationRule, currTabl.Fields.Count-cn)

# Validation Rule
tablRule = currTabl.ValidationRule
if tablRule <> "":
tablRule = " check(" + tablRule + ") "
self.writeLine("",",",1) # add a comma and CR previous line
self.writeLine(tablRule,"",0)

# Primary Key
pk=self.getPrimaryKey(currTabl)
if pk <> "":
self.writeLine("",",",1) # add a comma and CR previous line
self.writeLine(pk,"",0)

# End of table
self.writeLine("","",1) # terminate previous line
self.writeLine(');',"",1)

# Write table comment
try: sql = currTabl.Properties("Description").Value
except pythoncom.com_error: sql=""
if sql <> "":
sql = "comment on table " + chr(34) + currTabl.Name + chr(34) + " is " + chr(34) + sql + chr(34) +";"
self.writeLine(sql,"",1)

# Write column comments
for col in currTabl.Fields:
try: sql = col.Properties("Description").Value
except pythoncom.com_error: sql=""
if sql <> "":
sql = "comment on column " + chr(34) + currTabl.Name + chr(34) + "." + chr(34) + col.Name + chr(34) + " is " + chr(34) + sql + chr(34) + ";"
self.writeLine(sql,"",1)

# Write Indexes
self.writeIndexes(currTabl)

return

def writeColumn(self, colName, colType, length, requird, attributes, default, check, colRix):
# colRix: 0 based index of column from right side. 0 indicates rightmost column

if colType == const.dbByte: dataType = "Byte"
elif colType == const.dbInteger: dataType = "Integer"
elif colType == const.dbSingle: dataType = "Single"
elif colType == const.dbDouble: dataType = "Double"
elif colType == const.dbDate: dataType = "DateTime"
elif colType == const.dbLongBinary: dataType = "OLE"
elif colType == const.dbMemo: dataType = "Memo"
elif colType == const.dbCurrency: dataType = "Currency"
elif colType == const.dbLong:
if (attributes & const.dbAutoIncrField): dataType = "Counter"
else: dataType = "LongInteger"
elif colType == const.dbText:
if length == 0: dataType = "Text"
else: dataType = "char("+str(length)+")"
elif colType == const.dbBoolean:
dataType = "Bit"
if default == "Yes": default = "1"
else: default = "0"
else:
if length == 0: dataType = "Text"
else: dataType = "Text("+str(length)+")"

if default <> "":
defaultStr = "default " + default + " "
else: defaultStr = ""

if check <> "":
checkStr = "check(" + check + ") "
else:
checkStr = ""

if requird or (attributes & const.dbAutoIncrField):
mandatory = "not null "
else:
mandatory = ""

sql = " " + chr(34) + colName + chr(34) + " " + dataType + " " + defaultStr + checkStr + mandatory
if colRix > 0:
self.writeLine(sql,",",1)
else:
self.writeLine(sql,"",0)

return

def getPrimaryKey(self, currTabl):

# Get primary key fields
sql = ""
for idx in currTabl.Indexes:
if idx.Primary:
idxName = idx.Name
sql = " primary key "
cn=0
for col in idx.Fields:
cn=cn+1
sql = sql + chr(34) + col.Name + chr(34)
if idx.Fields.Count > cn : sql = sql + ","
return sql

def writeIndexes(self, currTabl):

# Write index definition
nIdx = -1
for idx in currTabl.Indexes:
nIdx = nIdx + 1
idxName = idx.Name
tablName = currTabl.Name
if idx.Primary:
idxName = tablName + "_PK"
elif idxName[:9] == "REFERENCE":
idxName = tablName + "_FK" + idxName[10:]
else:
idxName = tablName + "_IX" + str(nIdx)

sql = "create "
if idx.Unique: sql = sql + "unique "
if idx.Clustered: sql = sql + "clustered "
sql = sql + "index " + chr(34) + idxName + chr(34)
sql = sql + " on " + chr(34) + tablName + chr(34) + " ("

# Write Index Columns
cn=0
for col in idx.Fields:
cn = cn + 1
sql = sql + chr(34) + col.Name + chr(34)
if col.Attributes & const.dbDescending:
sql = sql + " desc"
else:
sql = sql + " asc"
if idx.Fields.Count > cn: sql = sql + ","

sql=sql + " );"

self.writeLine(sql,"",1)
return

def writeForeignKey(self, currRefr):

# Export foreign key
sql = "\nalter table " + chr(34) + currRefr.ForeignTable + chr(34)
self.writeLine(sql,"",1)

sql = " add foreign key ("
cn = 0
for col in currRefr.Fields:
cn = cn + 1
sql = sql + chr(34) + col.ForeignName + chr(34)
if currRefr.Fields.Count > cn: sql = sql + ","

sql = sql + ")"
self.writeLine(sql,"",1)

sql = " references " + chr(34) + currRefr.Table + chr(34) + " ("
cn = 0
for col in currRefr.Fields:
cn = cn + 1
sql = sql + chr(34) + col.Name + chr(34)
if currRefr.Fields.Count > cn: sql = sql + ","

sql = sql + ")"
if (currRefr.Attributes & const.dbRelationUpdateCascade) <> 0:
sql = sql + " on update cascade"
if (currRefr.Attributes & const.dbRelationDeleteCascade) <> 0:
sql = sql + " on delete cascade"
sql=sql+";"
self.writeLine(sql,"",1)

return

def writeQuery(self, currQry):

sql = "\ncreate view " + chr(34) + currQry.Name + chr(34) + " as"
self.writeLine(sql,"",1)

# Write Query text
sql=string.replace(currQry.SQL,chr(13),"") # Get rid of extra linefeeds
self.writeLine(sql,"",1)

# Write Query comment
try: sql = currQry.Properties("Description").Value
except pythoncom.com_error: sql=""
if sql <> "":
sql = "comment on table " + chr(34) + currQry.Name + chr(34) + " is " + chr(34) + sql + chr(34)
self.writeLine(sql,"",1)

return

def writeLine(self,strLine, delimit, newline):
# Used for controlling where lines terminate with a comma or other continuation mark
sqlfile.write(strLine)
if delimit: sqlfile.write(delimit)
if newline: sqlfile.write('\n')
return


if __name__ == '__main__':
if len(sys.argv)<2:
print "Usage: jet2sql.py infile.mdb outfile.sql"
else:
jetEng = jetReverse(sys.argv[1])
outfile = sys.argv[2]

sqlfile = open(outfile,'w')

print "\nReverse engineering %s to %s" % (jetEng.jetfilename, outfile)

# Tables
sys.stdout.write("\n Tables")
for tabl in jetEng.dtbs.TableDefs:
sys.stdout.write(".")
if tabl.Name[:4] <> "MSys" and tabl.Name[:4] <> "~TMP":
jetEng.writeTable(tabl)

# Relations / FKs
sys.stdout.write("\n Relations")
for fk in jetEng.dtbs.Relations:
sys.stdout.write(".")
jetEng.writeForeignKey(fk)

# Queries
sys.stdout.write("\n Queries")
for qry in jetEng.dtbs.QueryDefs:
sys.stdout.write(".")
jetEng.writeQuery(qry)

print "\n Done\n"

# Done
sqlfile.close()
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52267
jetEng.terminate()

标签: ,

星期日, 五月 04, 2008

赖勇浩:动态大比拼Python、Lua和Ruby

So which of the three languages is the best to use on your project? That depends a great deal on what you want to accomplish. To wrap up the book, I've outlined some of the pros and cons of each language in this section.
这三种语言中的哪一种更合适你的项目?很大程度取决于你想达到什么样的目标。作为一书的结尾,在这一节里,我会描述一下它们各自的优点和不足。
Python Pros and Cons
Python的优点和不足
The pros of Python are as follows:
Python的优点如下:
· Python has more extension modules than the other languages.
· Python比其它语言有更多扩展模块。
· Many online Python tutorials exist. There are also plenty of English books and reference materials, many sample scripts exist online, and there is a wealth of introductory material. The Python.org Website is a good place to start looking for these because it has sections for beginners, tutorials, guides organized by topic, and lists of links and references.
· 在网上可以找到很多Python教程。不仅如此,还有大量的英文书籍和资料。Python.org有很多为初学者准备的依主题组织的资料、教程和编程指南,此外还有很多链接和参考。
· Most folks really enjoy the syntax of the Python language because it appears clean and is easy to read.
· 很多人都喜欢Python语言的语法,因为它清晰易读。
· Python has an edge where libraries are concerned. There are many libraries, and, for the most part, they are well documented.
· Python在支持库上大占优势,因为它有很多库,而且大部分都有完善的文档支持。
· Lots of tools that tie into Python are available, and they are often easier to find than the tools for Lua and Ruby.
· 很多工具可以用于Python,但难以找到适用于Lua和Ruby的。
The cons of Python are as follows:
Python的不足:
· Existing Python debuggers are considered quirky and slow. Debugging support on Macintosh and consoles is even weaker.
· 现有的Python调试器诡异而且效率低下。在Macintosh(苹果计算机)和控制台下进行调试是一个梦魇。
· It can be difficult to bundle Python with other languages. There are lots of binary DLLs, and Python has (compared to the other languages) a large standard distribution.
· Python难以与其它语言集成,它有太多的二进制DLL,而且Python带了巨大的标准发布包。
· Lots of folks really dislike the white space sensitivity of Python syntax.
· 同样的,也有很多人不喜欢Python对空白符敏感的语法。
· Python can be quite slow at times, as everything is an object on the heap.
· 因为栈上的任何东西都是对象,所以Python有时候会慢得难以忍受。
Lua Pros and Cons
Lua的优点和不足
The pros of Lua are as follows:
Lua的优点:
· Lua is probably the fastest of the three languages and usually uses the least amount of runtime memory.
· Lua在这三种语言中是运行时速度最快而且占内在最少的。
· Lau has the smallest memory footprint for bundling.
· 集成Lua只会增加极少的内存占用率。
· The Lau C API is very well documented and has good examples for integrating with C.
· Lua的C API有着完备着文档和很好的例子,可以容易地通过C集成在软件里。
The cons of Lua are as follows:
Lua的不足:
· The documentation has improved but is still a bit sketchy overall. Of the three languages, Lua it is probably the least documented (the API being the exception), with the least amount of code comments. This makes for the largest ramp-up time to learn, and there isn't much in the way of introductory Lua material.
· 尽管Lua的文档已经增进不少,但仍然有所不足。三种语言中,Lua可能是文档最少的(API方面是个例外),因为代码中极少注释,这也增加了学习的难度。另外,对Lua的本质也没有什么介绍。
· There isn't a lot of built-in functionality for Lua. There is little support if you need to create a large, complex application.
· Lua内建的功能很少,并没有对创建大型的复杂应用程序提供足够支持。
· Lua could use a better garbage collectorthe current development is moving towards that now. Right now, Lua GC uses a very simple and traditional simple mark and sweep.
· Lua应该使用更好的垃圾收集机制,Lua现在的GC仍然使用非常简单而且传统的“标记和清除”方式。
Pros and Cons of Ruby
Ruby的优点和不足
The pros of Ruby are as follows:
Ruby的优点:
· Ruby possesses fairly good advanced debuggers.
· Ruby有极好的高级调试器。
· Ruby is object oriented from the ground up, and programmers who are OOP enthusiasts or who are used to the OOP paradigm will find the language extremely comfortable.
· Ruby是最彻底的面向对象语言,对于OOP狂热者和惯于使用OOP范式的程序员,他们将会发现Ruby是最适合他们的语言。
· Ruby has arguably the simplest syntax, with no real rules exceptions. Especially true for OOP enthusiasts.
· Ruby的语法极为简单,没有让人出乎意料规则,特别适合OOP行家的习惯。
The cons of Ruby are as follows:
Ruby的不足:
· Lack of English documentation.
· 英文文档极度缺乏。
· Fewer existing works and samples for games than with the other languages.
· 与其它语言相比,在游戏方面所作的工作和实例都少得多。

http://soft.zdnet.com.cn/software_zone/2007/0702/415264.shtml

标签: , , ,

星期三, 四月 16, 2008

配置 Python的wxWidgets可视开发环境

注:转载请注明出处

一、下载 Python 2.5.1
  这一步是必须做的,下载 Python 语言的 SDK
  下载地址(直接复制到迅雷):点击下载

  下载完成后安装 Python 2.5.1,注意安装路径中不要有空格,不然会引起一些问题。

二、下载 wxPython 2.8
  这将下载 Python 的可视化开发库,拥有它就可以进行可视化的开发了。
  下载地址:

    Unicode 版:点击下载
    Ansi 版:点击下载

  建议下载 Unicode 的,用 Ansi 版的话,组件标题不能写 Unicode 字符,代码包含 Unicode 字符也会出错。安装时注意,安装路径中不能有空格。
  到这一步为止,类库就齐全了,下面我们需要一个 IDE

三、下载 Boa Constructor
  Python 拥有非常多的开发环境,也就是 IDE。但是到现在为止,能完全支持可视开发的只有 Boa Constructor。使用它可以像使用 Delphi 那样,直接拖出控件进行快速的开发。
  下载地址:点击下载

  Boa Constructor 还是开源的,如果需要它的源码,可以点击下载
  注意,Boa Constructor 的安装路径也不能有空格。

四、配置 Boa Constructor
  打开 Boa Constructor,如果你是中文的系统,IDE 的语言会变成中文,你必须把它修改成英文的,在 工具->语言设置 菜单中将它换成英文。如果使用中文的 IDE,打开,保存文件时会发生错误(感谢纳米Baby提供这一信息,我自己的系统是英文的,试不出此问题)。
  点击 Tools->Python Interpreter Chooser,设置 Python.exe 的所在目录。
  关闭 Boa Constructor并重新启动它,配置即告完成。

五、一个简单的 Hello World 实例

  在工具栏中点击 wx.App 按钮,创建一个 wx 工程,这个工程将生成 2 个文件,一个是工程文件,另一个是窗体文件。

  然后将两个文件分别保存为 HelloWorld.py(工程文件) 和 Form.py(窗体文件)。在 Form.py 的显示窗口下按 F12,调出可视设计器。

  如上图所示,拖入一个 TextCtrl 和一个 Button。设置 TextCtrl 的 Name 为 txtHello,Value 为空。设置 Button 的 Name 为 btnHello,Label 为 Hello。

  然后我们要让 Button 按下时,TextCtrl 显示出 Hello World 字样。所以需要绑定 Button 的 OnButton 事件。在事件管理器中找到 OnButton,然后双击,点击 Apply 按钮。此时代码编辑器中会生成该事件相关的代码。

  如图所示,添加一行代码即可。然后运行程序,就能看到效果了。

标签: ,

星期二, 三月 18, 2008

Python+wxWidgets快速开发桌面小程序

作者:江南白衣

充分体验到知识循环再用的好处,原本对PythonwxWidgets没有接触的,天黑天亮之间,已经作了一个半成品的桌面程序出来。

1.选型
通常选型之后,都会迫切的告诉别人自认为正确的原因,这时候路过的人就比较不幸了。
我选Python和wxWidgets,是因为.......

因为是发布到网上的小程序,要它很小,Java和.Net这两个还算当红但要装虚拟机的笨家伙最先out了,而Python在py2exe之后压成rar才3M,如果有心思还可以弄得更小。
wxWidgets是因为它可以通行于Windows,Linux两个位面,另外Fox也能通用,不过wxWidgets是像SWT一样用Native Widgets的,在WinXP上比较好看。
用Python而不是C++,是为了快速开发。当然,心底里其实是贪好玩。本来喜欢Ruby的语法更纯洁一些,可惜wxRuby已经太久没更新了。

2.wxWidgets
所谓GUI框架,万变不离下面几点:
1.框架结构
拿个HelloWorld一看就懂,又是Application->Frame->Menu 的标准架构。

2.wxWidgets用法
来来去去还是Text框,选择框,按钮几个老面孔,在wxPython上把wxPython2.6-win32-docs-demos-2.6.1.0.exe档下载回来,就有C++版本的API手册与python版本的每个widgets的Demo Code。

3.控件与页面的Layout
一种方式是C# Winform和Swing那样在程序里生成组件和layout,经历过SWT手写代码画页面的折磨,再看到一层又一层的Container代码(wxWidgets里是Sizer)已经不觉得麻烦了。也有所见即所得的工具如BOA,不过毕竟没有Visual Studio for WinForm那么好,难以真正使用。
一种是像Delphi, VC或未来的XAML那样把控件和layout记在XML文件里。但我没有用。

4.事件分发机制
像 EVT_BUTTON(self,ID_UPLOAD, self.onUpload)这样的代码,挺简单的。

可见,只要有过GUI编程的经验,再学wxWidgets 很容易。
参考书:《Cross-Platform GUI Programming with wxWidgets》
《wxPython in Action》

3. Python
手边放一本Python的参考书,只要对动态语言有点感性认识,对着Sample Code能能猜就猜,猜不到就拿chm版的参考书来索引,也很容易入门。

最难的地方发生在遍历目录,那时候已经有点困了:
for root, dirs, files in os.walk('C:/projects/'):
print sum(getsize(join(root, name)) for name in files)

这是什么见鬼语法阿!!
原来os.walk('C:/projects") 的返回值是一个tuple。在C++ Boost库中接触过这个概念,平常函数都只能返回一个值,而tuple可以让你返回多个(这样就不用利用传址的参数来返回啦),所以就有了for root,dir,files in os.walk()这样的句子。
还有 print join(root,name) for name in files,原来python还有这种把闭包写在for的前面的简写法。

IDE最后还是用了Eclipse的插件PyDev,毕竟Eclipse看着比较舒服,其他编辑器做得那么难看,怎么还好意思收钱。

4.美化界面
因为wxWidgets用的是native widgets,不像Delphi,C# 和Swing有专门的look and feel 美化控件,所以美化的主要方式是为Toolbar和Button配上好看的图标,还有修饰整个软件的配色。
推荐Tango一个图标库:http://tango-project.org/ to make open source software beautiful...说出了我的心声啊,"顶尖儿的程序员必有完美主义艺术家之倾向。",目前的图标还不多,迅速更新中。

http://www.blogjava.net/calvin/archive/2005/11/18/20403.html

标签: , ,

辽ICP备05003652号
流风洄雪听天籁,轻云蔽日看落花

Powered by Blogger