俺这里想给大家初步介绍一下Python编程. 各位能看英文的,
最好是去看www.python.org上的其原作者Guido van Rossum
的入门介绍. (Python看成自1.6版以后就能处理Unicode的了,
故而也能很方便也处理中文了.) 俺这里只略提一二:
1)解释性语言一般都是完成任务快, 但所编的程序运行起来
有时会比编译语言编的程序(C/C++, Fortran, Pascal等)
要慢一个数量及以上. 虽然, 日常生活中仍然有许多事
俺们是不在乎它是0.0001秒内完成还是在0.1秒内完成,及
有时更在乎在短时间内完成一个很大的任务, 故而解释性
语言仍有很大市场. 更别提一般的解释性语言都可以用C/C++
等编成模块来处理关键性的任务.
2)常用的解释性语言有Perl, Python, Lisp/Scheme, Ruby等.
其中Perl算是运用最广泛的了; 但Perl的程序不易管理大概
也是举世公认的(它的宗义即为: "总有其它方法来完成这个
任务", 从而经常每个人有每个人的风格). Python相对Perl
的这点真是简单了不少. 它比Perl年轻不少, 但用户增长速
度很快. 目前好象是说Mandrake, Debian的系统管理在用
Perl, 但大哥大红帽则在用Python.
3)Python的交互式用法(可用作计算器, 或测试一个不熟悉的
函数等). 示例如下( >>>是Python的提示符 ):
$python
Python 2.1a1 (#4, Jan 29 2001, 20:22:47)
[GCC 2.95.2 19991024 (release)] on sunos5
Type "copyright", "credits" or "license" for more information.
>>> 3+4**2
19
>>> x=5
>>> y=6
>>> x/y
0
>>> x*1.0/y
0.83333333333333337
>>>
4)略解:
a)变量不用先定义类型, 直接由系统识别(大多解释性语言
都这样)
b)用行头空格数来标识块的起始, 省去了Perl/C/C++的{;}
没有{}匹配问题应该是省了不少头痛的. --- 这一点刚
开始会不太习惯, 熟了后真是很感谢G.V. Rossum的发明
c)没有了Perl中的$%@&等符号. (为方便, 下面俺将变量的
结果放在 ==> 的右边)
c.1) 字串(单引号等于双引号):
a = 'Well well study' + ', Day day up!'
则:
a[3] ==> 'l'
a[-1] ==> '!'
a[0:-1] ==> 'Well well study, Day day up!'
c.2) 数列(List), 相当于数组, 可以含不同类型
x = ['abc', 4, 'python']
则:
x[0] ==> 'abc'
x[1] ==> 4
c.3) 字典(Dictionary), 可以用字串作指标
mathScore = { 'xah': 59, 'tinybit': 99 }
则:
mathScore['tinybit'] ==> 99
d)函数, 可以用缺省参数:
def score (user='tinybit', whichExam='yesterday'):
if whichExam != 'yesterday': return 0
if user=='tinybit': return 99
else: return 59
于是:
score() ==> 99
score('xah') ==> 59
还可以用关键词来调用:
score(whichExam='tomorrow') ==> 0
e)模块, 俺就不多说了
f)类(Class), 面向对象的编程, 同上.
g)图形界面编程(GUI), 其缺省为基于TCL/TK上的Tkinter,
不过它的功能不是很多; 基于跨平台wxWindows库的
wxPython功能要强不少(尚未中文化, 有待各位努力).
还有基于Qt和Gtk库的, 不过Gtk好象目前还不能在Windows
上很好的运行, Qt虽能, 也很成熟, 但若在Windows上运行
它原则上要向TrollTech上贡$1,500的, 不象wxWindows完全
免费.
好了, 俺就先多嘴至此. 各位同仁感兴趣的, 该去 python.org
当下它的入门简介, 俺有80-90%的把握that你会喜欢它的.
循环, 条件 及 函数编程工具
俺在上篇中大略介绍了Python的变量与函数, 这里稍作补充来解释一下Python
的循环, 条件及函数编程工具. (还是按上篇的方法: 将变量或函数
的结果放在 ==> 的右边)
1) 循环
首先得更正上篇中一个小错误: Python的范围含首不含尾, 所以
若:
a = 'Well well study' + ', Day day up!'
则:
a[0:-1] ==> 'Well well study, Day day up' #不包括最后的'!'
Python还有一个专门的范围函数: range. 例如:
range(4) ==> [0, 1, 2, 3]
range(2, 5) ==> [2, 3, 4]
它在for循环中常用.如:
total = 0
for i in range(11): total += i
最后 total ==> 55
循环也可以用 while, 如:
total, i = 0, 0
while i<11: total += i; i += 1
2) 条件编程是:
if 条件语句 : 命令1
elif 条件语句: 命令2
else: 命令3
条件语句中相当于C的&&是and, 相当于||是or; 其中不允许赋值,
以避免C/C++中的不小心将 == 写成 = 后这一很常见的头痛. 例:
total, i = 0, 0
while 1:
total += i; i += 1
if i>11 or total > 55: break
3) 函数编程工具 (map/filter/reduce)
这几个工具, 可以帮你在处理数列时只调用一次函数, 从而在简
单处理大批数据时, 有可能大幅提高程度的执行速度.
map(函数f, 数列l) ==> [ f(l[0]), f(l[0]), ... ]
filter (f, l) ==> 只在l中剩下对f是真的值
reduce (f, l) ==> 用l中头两个数作参数调用f, 产生的结果再
==> 与l中的第三个数作参数去调用f, 如此到底
如:
def add(x,y): return x+y
reduce ( add, range(1,11) ) ==> 55
def PingFang(x): return x*x
map ( PingFang, range(1,5) ) ==> [1, 4, 9, 16]
def JiShu (x): return x%2 == 1
filter ( JiShu, range(8) ) ==> [1, 3, 5, 7]
4) 若想让你编的脚本能直接执行, 只要象其他Shell脚本一样, 在脚本第一
行头加上Python的路径即可.
#!/PythonPath/python #或用: #!/usr/bin/env python
可以用sys.argv, len(sys.argv) 得到C/C++中的argv, argc. (若引入:
from sys import argv
之后, 上面的sys.argv 就可直接写成 argv --- 下次俺提到模块时再
细说. )
-----------------------------------------------------------------------------
-
模块与类
头两篇都没提到Python的模块与类, 这里来补充一下:
1)模块(Module)
你可以将几个函数编好放在一个文件中, 比方说你的
score.py文件中有: mathScore(), physScore(),
chemScore() 等几个函数; 将之放在当前目录或是PYTHON
的系统调用目录中; 于是你在当前目录中的另一个文件中,
就可以有两种方法调用:
a)
import score
score.mathScore('xah')
...
b)
from score import *
#或可用 from score import mathScore
mathScore('xah')
...
第二种方法引入模块后,调用时就不要前缀score了; 当然
第二种调用方法容易重名. 总之, Python的模块编写是很
简单的. (稍麻烦一点的是你想用C/C++来编一个Python模
块.) 俺自己就把常用的物理常数编在physConst.py中,将
之放到Python安装目录下.
在简介(二)中俺提到过from sys import argv之事, 因为
Python作为缺省已经以"import sys"的形式引入了sys 模
块, 所以你可以直接把 sys.argv 当作C/C++中
main(int argc, char *argv[])
里的 argv 来用; 也可用"from sys import argv"再引入
一次, 于是后面皆可直接呼之为 argv
模块文件的第一个有效行(非注释行)可以是一行字串, 或
是夹在""" 与 """之间的若干行文字.(同样, 单引号等于
双引号: ''' == """ .) 函数的定义也一样. 于是日后
别人或自己在调用该函数/模块时, 即可用:
print 该函数/模块.__doc__
来看这个函数/模块的说明.
2)类(Class)
class MyClass(父类): #从父类遗传一个子类: MyClass
def method1(self, ...):
...
def mether2(self, ...):
self.method1()
...
类的实体化(instantiation)和调用为:
c = MyClass(...)
c.method1(...)
c.method2(...)
这里有方法(method)和函数(function)的区别在.
method(args) == function(对象, args)
所以在类的函数定义中, 第一个参数皆为对象. 通常情况下, 都将其
写为self. self本身并无实义, 这只是Python的习惯, 可能老的类浏
览软件会依靠self. 实体化后的调用, 如上面 c.method1(...) 就是
方法调用, 故不需要写出第一个对象参数.
self还有一个用法. 因Python没有用Private/Public/Protected, 它
的函数中定义的变量都是局部变量. 当在一个函数之内调用类的变量
或函数时要加上self. 如:
class My:
x = 3
def PingFang(self): return self.x ** 2
def LiFang(self): return self.PingFang() * self.x
于是当实体化: m = My() 后,
m.PingFang() ==> 9
m.LiFang() ==> 27
当在一个函数中调用另外一个函数的变量时, 两个函数中的变量都加
上"self."
通常还可定义一个相当于C++中类的初始构造器(constructor)的一个
函数:
def __init__(self, ...):
...
类中的变量通常是不能隐形的, 在类的定义之外还可任意改变, 甚至
添加新变量, 与删除新变量. 但__AA_形式的变量是特别的 ( 前头最
少两个下划线, 尾部最多一个下划线.), 它相当于C++中的Protected
变量.
Python的类有点绕脑筋, 不过各位若去看看它的图形界面编程(GUI),就
会发现它还是蛮有用和蛮好用的. 感兴趣的, 可以到 python.org 和
wxPython.org上走走.
诡计之一: 对简单的任务, 俺通常将之写为非面向对象的, :-)
图象界面编程 (GUI)
首先得对简介(三)中类的方法与函数的差别作一小更正(幸得Kh9
先生指正于其后的文章点评中):
在类的实体化:
对象 = 类(初始化参数)
之后对对象方法的调用:
对象.方法(参数)
其实是相当于调用如下函数:
类.方法(对象, 参数)
因为Python是用C而不是C++写的. 大家可以看到其作
者对类的处理还是蛮合理的.
对类的了解可以在其图象界面编程(GUI)中得以深入.俺自己当初
学C时就对它的画图功能十分感兴趣,曾用之画过不少数学解集,
如混沌学中气象预报的Lorentz方程 (正发现网上有Java展示:
http://www.wcinet.net/~joshw/na/chaos/Lorentz.html
和分形学中的Mandelbrot集合等. 所以对Python的图象编程也趣
味盎然.
Python的GUI主要是与其它己存在图形库的结合. 目前主要有:基
于Tcl/Tk库的Tkinter,基于wxWindows库的wxPython,基于Qt/Kde
库的PyQt/PyKde和基于Gtk+/Gnome库的PyGtk/PyGnome.其他还有
基于FlTk库的FlPy, 基于Fox库的FoxPy等.
Python自带了Tkinter,其编程之简单也基本类似Tcl/Tk, 但Tk的
对象不很丰富,所产生的图形也不是很漂亮.俺曾看到网上有人比
较过wxPython与Tkinter的画点速度,发现wxPython要快一个数量
级.这可能是因Tkinter不仅要调用Python还得用Tcl两个脚本语
言之故.对于PyQt,俺没能在俺的Mandrake7.2上编译成功,所以就
没学它了, 不过据说也拥有稍小于wxPython的用户群;PyGtk目前
还不如wxPython和PyQt成熟. 下面俺就略说一下Tkinter.就入门
而言, Tkinter还是值得一瞄的.而且网上有很多关于它的入门介
绍, 如:
http://www.pythonware.com/library/an-introduction-to-tkinter.htm
http://www.python.org/doc/life-preserver/
也正好看到OSO就有<<Teach Yourself Python>>的源码下载,其后
面几章就是Tkinter的样例, 其中一个就是画Mandelbrot集的.
a)Tk与Tkinter对照:
Tk ==> Tkinter
button .b ==> b=Button() #在根窗口中定义一个按钮
button .panel.b ==> b=Button(panel) #在面板中定义一个按钮.
button .b -fg red ==> b=Button(fg="red") #设置前景色
.b configure -fg red ==> b["fg"]=red #部件产生后再配置
==> b.config(fg="red") #第二种方法
pack .b -side left ==> b.pack(side="left") #列入右边并显示
b)最简单的例子 (一个窗口中含字串: Hello, world!)
from Tkinter import *
root = Tk() #产生一个根窗口
l = Label(root, text="Hello, world!")# 产生一个标识
l.pack()
root.mainloop() #进入主循环, 有事件则运行, 无事就等着
c)仍是十分简单的例子(一个窗口中两个按钮:Quit和Hello)
from Tkinter import * #引入Tkinter模块
class App: #定义一个类
def __init__(self, master): #类的构造器, 相当于C++的constructor
frame = Frame(master) #产生一个框架
frame.pack()
button = Button(frame, text="QUIT", fg="red", command=frame.quit)
button.pack(side=LEFT)
hi_there = Button(frame, text="Hello", command=self.say_hi)
#self.say_hi是调用类的函数 say_hi()
hi_there.pack(side=LEFT)
def say_hi(self):
print "hi there, everyone!"
root = Tk()
app = App(root) #上面__init__有两个参数, self只是对象
root.mainloop()
上面b), c)取自:
http://www.pythonware.com/library/tkinter/introduction/
因b)简单, c)介绍了类的用法. 在c)中俺将它原来的self.button
和self.hi_there改成了button和hi_there, 因为不会在类的其它
地方调用这两个器件. 俺刚才试过, 没问题的.
另外,OSO发文时好象不能发图片.俺自己倒是省了点事.读者可以到
上面所给地址去看程序运行结果, 及更多内容. 俺这里只是想给大
家一个初始印象.
顺便说一下,俺本来还想给出wxPython的两个例子,幸好到OSO上的
搜索了一下, 原来limodou先生已经将O'Reilly书:
<<Python Programming on Win32>>
中有关wxPython的内容全译了:
http://www.oso.com.cn/read_article.php?article_id=4134
而且是最近才译的, 看来 "英雄所见略同", :-) 不过俺发现他文章
样例程序中的行头空格全没了 --- 这样的Python程序是无法运行的.
也许是浏览器将之当作Html文件了.所以推荐其原网页供各位下载样
例源码:
http://www.oreilly.com/catalog/pythonwin32/chapter/ch20.html
(其实oreilly.com上仅仅给了<<Win32上的Python编程>>中的两章作
样子,但幸运的是其中就有这章GUI编程.) wxPython.org上的简介还
没有O'Reilly上的详细. wxPython的作者及wxWindows的几位一起开
了个wxpros.com, 来提供支持服务(如培训,付费答疑等), 愿其成功,
或至少能供养肚子继续发展wxPython, :-)
杂类
这里俺想补充几点俺的前面四篇中尚未提及但仍很有用的地方. 下面
将要出现的 ...是Python的第二提示符, 表示继续一个不完整的命令
*)Python中的每个变量都是对象 --- Python特有的对象, 并不一定
都是 "面向对象的编程" 中的对象
*)第一有效行(非解释行), 其行首必须没有空格(在Python中, 表格
键Tab 缺省是等于8个空格.)
*)续行可以用行末的 '\', 注意其后必需是回车/换行; 对于包在大,
中, 小括号中的若干行, 系统都缺省作续在一起的一行. 但不能把
一个变量名分开放在两行上. 如:
>>> score = {'xah':59,
... 'you':99}
>>>
>>> score\
... ['xah']
59
>>> scor\
... e['xah'] #错误
File "<stdin>", line 2
e['xah']
^
SyntaxError: invalid syntax
>>>
*)交互式用法中的下划线: _ , 是上面一行命令运行的结果. 如:
>>> 3+5
8
>>> _ * 7
56
*)屏幕输出
在print最后加一逗号, 就不会自动输出'\n', 而输出一空格;
也可用格式符:
>>> print 'a'; print 'b'
a
b
>>> print 'a',; print 'b' #第一句后加了一个逗号
a b
>>> print '%x %s' % (11, 'abc') #多变量时须用小括号括起,见下面: Tuple
b abc
再重提一下, 包在匹配的 三个单引号或三个双引号之间的字
串, 可以是多行, 相当于HTML中的<PRE>和</PRE>, 即原样在
屏幕上输出. 也可对它们用格式符:
>>> a = ''' pytho
... n is %s!''' % 'great'
>>> a
' pytho\012n is great!' #Python用8进制显示控制字符: \n == \012
>>> print a
pytho
n is great!
>>>
Python 2.0版之后就可能用 >>stderr 来打印到标准错误输出:
>>> from sys import stderr
>>> print >> stderr, 'ok'
ok
2.0版之前好象是用文件形式: stderr.write('ok')
*)字串变数字, 数字变字串:
>>> int('123')
123
>>> float('123')
123.0
>>> eval('123') #随所给字串, 既可产生整数, 也可浮点数
123
>>> str(123) #数字到字串
'123'
>>> `123` #反向单引号, 还可用函数: repr(数字变量)
'123'
*)屏幕输入:
字串输入: s = raw_input(提示字串)
数字输入: x = input(提示字串) #相当于: eval(raw_input())
*)字串按空格或其它用户定义的分隔符来分隔.
Python 2.0版以后的, 可以用:
>>> a='123 321 456'
>>> a.split()
['123', '321', '456']
>>> a.split('2')
['1', '3 3', '1 456']
>>> 'AA'.join( a.split('2') ) #按分隔符'AA'将字串数列合并
'1AA3 3AA1 456'
但2.0(或至少1.6 ?)以前必须要引入string模块: (也即2.0
将原本在string模块中的不少函数并入字串的方法中去了,
但不是全部):
>>> from string import split, join
split(a,'2')
['1', '3 3', '1 456']
>>> join ( split(a,'2'), 'AA') #同上, 但调用了函数
'1AA3 3AA1 456'
*)交互式下可以用dir()来看从模块中引入了什么函数与变量:
>>> import math
>>> dir(math)
['__doc__', '__file__', '__name__', 'acos', 'asin',
'atan', 'atan2', 'ceil', 'cos', 'cosh', 'e', 'exp'
, 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp
', 'log', 'log10', 'modf', 'pi', 'pow', 'sin', 'sin
h', 'sqrt', 'tan', 'tanh']
看函数/模块的说明(函数/模块中的第一行字串, 或多行位于
成对的''', """之间):
>>> import math
>>> print math.__doc__
This module is always available. It provides access to the
mathematical functions defined by the C standard.
>>> print math.sin.__doc__
sin(x)
Return the sine of x.
>>>
*)文件
打开:
f = open("My.py") #只读
f = open("My.py", "r") #只读
f = open("My.py", 'r+b')#可读可写, 二进制文件
f = open("tmpFile", 'w')#只写
读:
s = f.read(字节数) #读给定字节数的内容
text = f.read() #读整个文件, 得到一字串
line = f.readline() #读一行(含换行符: '\n')
lines = f.readlines() #读整个文件, 得到字串数列
#lines[-1]是最末一行(含'\n'), 等等
写:
f.write('AAAbbb\n') #写一个字串
f.writelines(lines) #写字串所组成的数列
关闭:
f.close()
*)lambda函数
来自Lisp/Scheme, 好象是只能有一个执行句子. 可能主要是
用来简写一个函数的定义.
>>> f = lambda a, b, c : (a + b ) * c
>>> f(1,2,3)
9
看样子它有点类似于C/C++中的:
#define max(A, B) (A)>(B) ? (A) : (B)
*)空白类可以来作C中的"struct"功能:
>>> class My: pass
... #其中pass是不执行任何命令. 大概是由于分号在Python
... #中不太起作用, 所以引入"pass". 而C中就可以用:
... # for (;;);
... #来"等你等到天尽头".
...
>>> xah = My()
>>> xah.birthDay = 1
>>> xah.birthYear = 3000
>>> xah.birthYear
3000
>>>
*)错误处理
通常Python若出错误, 即会自动退出. 但你可以用
try : 可能出错语句
except 特定错误 : 出错后要执行的命令
来处理. 如:
>>> 1/0 #除0错误
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ZeroDivisionError: integer division or modulo by zero
>>> try: 1/0
... except ZeroDivisionError:
... print "ok"
...
ok
*)Tuple, 俺在<<英华大字典>>上都没找到其译文. 马苏安的星际
译王将之译为"元组". 英文解释似乎也很强调它的有序性.这里
俺就暂用"元组".
Python的元组是用小括号括起来的变量, 常数, 函数等对象的组
合, 虽然有时候小括号可以省略. 如俺以前给出过:
total, i = 0, 0
其实就是元组赋值:
(total, i) = (0, 0)
*)字串和元组皆是一经产生就不可再变更, 只能另赋新值. 这也是
元组不同数列之处. 数列和字典皆可在产生之后变更. 如:
>>> s="abc"
>>> s[2] = 'D' #错误:
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: object doesn't support item assignment
>>> t = (3, 5)
>>> t[0] = 4 #错误
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: object doesn't support item assignment
但可以用其片段来组成一个另变量:
>>> s='abc'
>>> s2 = s[1:-1] + 'd'
>>> s2
'bd'
>>> s='def'
>>> s
'def'
元组中的可变更变量也可另赋值:
>>> x, y = 3, 5
>>> a=(x,y)
>>> a
(3, 5)
>>> y=4
>>> a
(3, 5)
>>> x,y=3, [4,5]
>>> z=x, y
>>> z
(3, [4, 5])
>>> y[0] = 2
>>> z
(3, [2, 5])
>>>
*)赋值,
跟能常所说的(如C/C++)赋值有些不一样.
变量赋给变量时, 只是增加了对同一对象的参考(Reference),
而不产生新变量. 如:
>>> l=[3,4]
>>> l2=l
>>> l[0]=-1
>>> l
[-1, 4]
>>> l2
[-1, 4]
而俺发现用l2 = l[0:]就不一样:
>>> l=[3,4]
>>> l2=l[0:]
>>> l[0]=-1
>>> l
[-1, 4]
>>> l2
[3, 4]
但对不可变更的对象, 因其不可变更, 或只能另赋新值, 所以
只表现为常见的"赋值即产生新对象"的样子:
>>> s='abc'
>>> ss = s
>>> ss
'abc'
>>> s='345'
>>> s
'345'
>>> ss
'abc'
本节结语: 希望大家不要被俺绕糊涂了, 俺只是想提供一些Python
与通常的语言, 如C/C++, 相比而不同之处. 总的来说, Python还是
蛮好用的. wxPython作者, 罗宾 . 邓恩 (Robin Dunn) 就在网上说,
他个人习惯是一切编程皆用Python; 即使真需要速度, 他也将C/C++
编成Python模块.
到此为止对Python还很感兴趣的同志, 可以去当Python的库参考了.
(mpage可以4合1, 加上正反面打印, python.org上的400页库参考
你50张纸就行了, 只要你视力不是太弱可以看小号字体, :-) )
-
pygtk 的图象编程
俺最近又稍学了点pygtk, 贴出来给大家分享.
俺去学pygtk的原因是, 俺发现在俺的机子上pygtk比wxpython在
启动时要几乎快上一倍(1-2秒相对于2-5秒); 并且俺发现一个简
单的按钮显示, wxpython的程序运行起来要占约10-12M内存, 而
pygtk的只要约5-6M.
后来俺就到wxpython的用户邮件列表上发问, 那里的人还很热心
地作了解释, 说启动速度和内存是因为UNIX下的wxGtk在是对Gtk
库进行包装的结果, 并说启动之后的执行速度二者应无显蓍差别.
wxWindows故而拥有很好的移植性. 还有人指出了二者其它异同.
大意是pygtk还可以使用主题色彩配置(themes), 而且gnomepy还
可以使用libglade库来简化很多编程任务; 但wxpython的小器件
(widget)还是要比目前的pygtk要丰富. 关于Gtk在MS Windows上
的运行, 有人说很稳定了, 也有人说每5分钟死一次机. 另外,俺
还瞄了瞄二者用户列表上的帖子数量, 发现wxpython的约为pygtk
的两倍左右.
所以总的看来, 还是各有千秋. 大家不妨也来瞄瞄pygtk.
Gtk+与Python的结合早就有人捣弄了, 不过目前最正统还是
James Henstridge做的,看网址他好象是澳大利亚人. pygtk的
主页在:
http://www.daa.com.au/~james/pygtk/
而在这里有pygnome的入门简介:
http://laguna.fmedic.unam.mx/~daniel/pygtutorial/
俺下面就取其中的两个例子(也是pygtk源程序中examples/simple
目录中的两个程序)稍作解释.
pygtk目前的稳定版是0.6.6; 作者说: 别看它版本还不高, 里
面的小器件还真不少, Gtk+ 1.2的玩意差不多全包括了. 咱这
就过来瞧一瞧.
pygtk有两种实现. 最老早的是基于C语言的函数调用形式, 这
倒与Gtk+本身很相近; 后来采用了面向对象的形式, 感觉要简
洁不少. 请看:
1)"世界好!"的C语言调用形式
(来自pygtk源程序中的examples/simple/hello1.py)
#!/usr/bin/env python #让程序可执行
from _gtk import * #引入pygtk的C函数模块, gtk前有下划线
from GTK import * #引入常用变量模块
def hello(*args): #函数定义: 屏幕显示"世界好"
print "Hello World"
gtk_widget_destroy(window)
def destroy(*args): #退出函数定义
gtk_widget_hide(window)
gtk_main_quit()
gtk_init() #Gtk初始化
window = gtk_window_new(WINDOW_TOPLEVEL) #产生一个窗口
gtk_signal_connect(window, "destroy", destroy) #退出信号连接
gtk_container_set_border_width(window, 10) #边界宽度设定
button = gtk_button_new_with_label("Hello World")#产生一个按钮
gtk_signal_connect(button, "clicked", hello) #鼠标点击传到函数
gtk_container_add(window, button) #将按钮加入到窗口中
gtk_widget_show(button) #显示按钮
gtk_widget_show(window) #显示窗口
gtk_main() #等待鼠标动作
2)"世界好!"的面向对象的形式
(来自pygtk源程序中的examples/simple/hello2.py)
#!/usr/bin/env python
from gtk import * #引入pygtk的面向对象的模块, gtk前无下划线
def hello(*args):
print "Hello World"
window.destroy()
def destroy(*args):
window.hide()
mainquit()
window = GtkWindow(WINDOW_TOPLEVEL) #产生一个窗口
window.connect("destroy", destroy) #退出信号连接
window.set_border_width(10) #边界宽度设定
button = GtkButton("Hello World") #产生一个按钮
button.connect("clicked", hello) #鼠标点击传到函数
window.add(button) #将按钮加入到窗口中
button.show() #显示按钮
window.show() #显示窗口
mainloop() #等待鼠标动作
===========
大家是不是也觉得第二种方法要简洁 ? pygtk的作者好象也是推荐
大家用第二种方式. 对大一点的程序, 照样可以用类(class)来把
它表达的很清楚.
俺就不多说了, 各位感兴趣的, 可以去上面的入门介绍中看看它们
运行的屏幕取像(screenshot), 再去当下pygtk的源程序装上(很小,
300k, 也很容易装上), 并运行一下它里面examples目录下的样例,
就会很了解pygtk能干什么活了. 当你自己想用它编简单任务时,直
接在其某个样例的基础进行加工是最省事的了.
最好是去看www.python.org上的其原作者Guido van Rossum
的入门介绍. (Python看成自1.6版以后就能处理Unicode的了,
故而也能很方便也处理中文了.) 俺这里只略提一二:
1)解释性语言一般都是完成任务快, 但所编的程序运行起来
有时会比编译语言编的程序(C/C++, Fortran, Pascal等)
要慢一个数量及以上. 虽然, 日常生活中仍然有许多事
俺们是不在乎它是0.0001秒内完成还是在0.1秒内完成,及
有时更在乎在短时间内完成一个很大的任务, 故而解释性
语言仍有很大市场. 更别提一般的解释性语言都可以用C/C++
等编成模块来处理关键性的任务.
2)常用的解释性语言有Perl, Python, Lisp/Scheme, Ruby等.
其中Perl算是运用最广泛的了; 但Perl的程序不易管理大概
也是举世公认的(它的宗义即为: "总有其它方法来完成这个
任务", 从而经常每个人有每个人的风格). Python相对Perl
的这点真是简单了不少. 它比Perl年轻不少, 但用户增长速
度很快. 目前好象是说Mandrake, Debian的系统管理在用
Perl, 但大哥大红帽则在用Python.
3)Python的交互式用法(可用作计算器, 或测试一个不熟悉的
函数等). 示例如下( >>>是Python的提示符 ):
$python
Python 2.1a1 (#4, Jan 29 2001, 20:22:47)
[GCC 2.95.2 19991024 (release)] on sunos5
Type "copyright", "credits" or "license" for more information.
>>> 3+4**2
19
>>> x=5
>>> y=6
>>> x/y
0
>>> x*1.0/y
0.83333333333333337
>>>
4)略解:
a)变量不用先定义类型, 直接由系统识别(大多解释性语言
都这样)
b)用行头空格数来标识块的起始, 省去了Perl/C/C++的{;}
没有{}匹配问题应该是省了不少头痛的. --- 这一点刚
开始会不太习惯, 熟了后真是很感谢G.V. Rossum的发明
c)没有了Perl中的$%@&等符号. (为方便, 下面俺将变量的
结果放在 ==> 的右边)
c.1) 字串(单引号等于双引号):
a = 'Well well study' + ', Day day up!'
则:
a[3] ==> 'l'
a[-1] ==> '!'
a[0:-1] ==> 'Well well study, Day day up!'
c.2) 数列(List), 相当于数组, 可以含不同类型
x = ['abc', 4, 'python']
则:
x[0] ==> 'abc'
x[1] ==> 4
c.3) 字典(Dictionary), 可以用字串作指标
mathScore = { 'xah': 59, 'tinybit': 99 }
则:
mathScore['tinybit'] ==> 99
d)函数, 可以用缺省参数:
def score (user='tinybit', whichExam='yesterday'):
if whichExam != 'yesterday': return 0
if user=='tinybit': return 99
else: return 59
于是:
score() ==> 99
score('xah') ==> 59
还可以用关键词来调用:
score(whichExam='tomorrow') ==> 0
e)模块, 俺就不多说了
f)类(Class), 面向对象的编程, 同上.
g)图形界面编程(GUI), 其缺省为基于TCL/TK上的Tkinter,
不过它的功能不是很多; 基于跨平台wxWindows库的
wxPython功能要强不少(尚未中文化, 有待各位努力).
还有基于Qt和Gtk库的, 不过Gtk好象目前还不能在Windows
上很好的运行, Qt虽能, 也很成熟, 但若在Windows上运行
它原则上要向TrollTech上贡$1,500的, 不象wxWindows完全
免费.
好了, 俺就先多嘴至此. 各位同仁感兴趣的, 该去 python.org
当下它的入门简介, 俺有80-90%的把握that你会喜欢它的.
循环, 条件 及 函数编程工具
俺在上篇中大略介绍了Python的变量与函数, 这里稍作补充来解释一下Python
的循环, 条件及函数编程工具. (还是按上篇的方法: 将变量或函数
的结果放在 ==> 的右边)
1) 循环
首先得更正上篇中一个小错误: Python的范围含首不含尾, 所以
若:
a = 'Well well study' + ', Day day up!'
则:
a[0:-1] ==> 'Well well study, Day day up' #不包括最后的'!'
Python还有一个专门的范围函数: range. 例如:
range(4) ==> [0, 1, 2, 3]
range(2, 5) ==> [2, 3, 4]
它在for循环中常用.如:
total = 0
for i in range(11): total += i
最后 total ==> 55
循环也可以用 while, 如:
total, i = 0, 0
while i<11: total += i; i += 1
2) 条件编程是:
if 条件语句 : 命令1
elif 条件语句: 命令2
else: 命令3
条件语句中相当于C的&&是and, 相当于||是or; 其中不允许赋值,
以避免C/C++中的不小心将 == 写成 = 后这一很常见的头痛. 例:
total, i = 0, 0
while 1:
total += i; i += 1
if i>11 or total > 55: break
3) 函数编程工具 (map/filter/reduce)
这几个工具, 可以帮你在处理数列时只调用一次函数, 从而在简
单处理大批数据时, 有可能大幅提高程度的执行速度.
map(函数f, 数列l) ==> [ f(l[0]), f(l[0]), ... ]
filter (f, l) ==> 只在l中剩下对f是真的值
reduce (f, l) ==> 用l中头两个数作参数调用f, 产生的结果再
==> 与l中的第三个数作参数去调用f, 如此到底
如:
def add(x,y): return x+y
reduce ( add, range(1,11) ) ==> 55
def PingFang(x): return x*x
map ( PingFang, range(1,5) ) ==> [1, 4, 9, 16]
def JiShu (x): return x%2 == 1
filter ( JiShu, range(8) ) ==> [1, 3, 5, 7]
4) 若想让你编的脚本能直接执行, 只要象其他Shell脚本一样, 在脚本第一
行头加上Python的路径即可.
#!/PythonPath/python #或用: #!/usr/bin/env python
可以用sys.argv, len(sys.argv) 得到C/C++中的argv, argc. (若引入:
from sys import argv
之后, 上面的sys.argv 就可直接写成 argv --- 下次俺提到模块时再
细说. )
-----------------------------------------------------------------------------
-
模块与类
头两篇都没提到Python的模块与类, 这里来补充一下:
1)模块(Module)
你可以将几个函数编好放在一个文件中, 比方说你的
score.py文件中有: mathScore(), physScore(),
chemScore() 等几个函数; 将之放在当前目录或是PYTHON
的系统调用目录中; 于是你在当前目录中的另一个文件中,
就可以有两种方法调用:
a)
import score
score.mathScore('xah')
...
b)
from score import *
#或可用 from score import mathScore
mathScore('xah')
...
第二种方法引入模块后,调用时就不要前缀score了; 当然
第二种调用方法容易重名. 总之, Python的模块编写是很
简单的. (稍麻烦一点的是你想用C/C++来编一个Python模
块.) 俺自己就把常用的物理常数编在physConst.py中,将
之放到Python安装目录下.
在简介(二)中俺提到过from sys import argv之事, 因为
Python作为缺省已经以"import sys"的形式引入了sys 模
块, 所以你可以直接把 sys.argv 当作C/C++中
main(int argc, char *argv[])
里的 argv 来用; 也可用"from sys import argv"再引入
一次, 于是后面皆可直接呼之为 argv
模块文件的第一个有效行(非注释行)可以是一行字串, 或
是夹在""" 与 """之间的若干行文字.(同样, 单引号等于
双引号: ''' == """ .) 函数的定义也一样. 于是日后
别人或自己在调用该函数/模块时, 即可用:
print 该函数/模块.__doc__
来看这个函数/模块的说明.
2)类(Class)
class MyClass(父类): #从父类遗传一个子类: MyClass
def method1(self, ...):
...
def mether2(self, ...):
self.method1()
...
类的实体化(instantiation)和调用为:
c = MyClass(...)
c.method1(...)
c.method2(...)
这里有方法(method)和函数(function)的区别在.
method(args) == function(对象, args)
所以在类的函数定义中, 第一个参数皆为对象. 通常情况下, 都将其
写为self. self本身并无实义, 这只是Python的习惯, 可能老的类浏
览软件会依靠self. 实体化后的调用, 如上面 c.method1(...) 就是
方法调用, 故不需要写出第一个对象参数.
self还有一个用法. 因Python没有用Private/Public/Protected, 它
的函数中定义的变量都是局部变量. 当在一个函数之内调用类的变量
或函数时要加上self. 如:
class My:
x = 3
def PingFang(self): return self.x ** 2
def LiFang(self): return self.PingFang() * self.x
于是当实体化: m = My() 后,
m.PingFang() ==> 9
m.LiFang() ==> 27
当在一个函数中调用另外一个函数的变量时, 两个函数中的变量都加
上"self."
通常还可定义一个相当于C++中类的初始构造器(constructor)的一个
函数:
def __init__(self, ...):
...
类中的变量通常是不能隐形的, 在类的定义之外还可任意改变, 甚至
添加新变量, 与删除新变量. 但__AA_形式的变量是特别的 ( 前头最
少两个下划线, 尾部最多一个下划线.), 它相当于C++中的Protected
变量.
Python的类有点绕脑筋, 不过各位若去看看它的图形界面编程(GUI),就
会发现它还是蛮有用和蛮好用的. 感兴趣的, 可以到 python.org 和
wxPython.org上走走.
诡计之一: 对简单的任务, 俺通常将之写为非面向对象的, :-)
图象界面编程 (GUI)
首先得对简介(三)中类的方法与函数的差别作一小更正(幸得Kh9
先生指正于其后的文章点评中):
在类的实体化:
对象 = 类(初始化参数)
之后对对象方法的调用:
对象.方法(参数)
其实是相当于调用如下函数:
类.方法(对象, 参数)
因为Python是用C而不是C++写的. 大家可以看到其作
者对类的处理还是蛮合理的.
对类的了解可以在其图象界面编程(GUI)中得以深入.俺自己当初
学C时就对它的画图功能十分感兴趣,曾用之画过不少数学解集,
如混沌学中气象预报的Lorentz方程 (正发现网上有Java展示:
http://www.wcinet.net/~joshw/na/chaos/Lorentz.html
和分形学中的Mandelbrot集合等. 所以对Python的图象编程也趣
味盎然.
Python的GUI主要是与其它己存在图形库的结合. 目前主要有:基
于Tcl/Tk库的Tkinter,基于wxWindows库的wxPython,基于Qt/Kde
库的PyQt/PyKde和基于Gtk+/Gnome库的PyGtk/PyGnome.其他还有
基于FlTk库的FlPy, 基于Fox库的FoxPy等.
Python自带了Tkinter,其编程之简单也基本类似Tcl/Tk, 但Tk的
对象不很丰富,所产生的图形也不是很漂亮.俺曾看到网上有人比
较过wxPython与Tkinter的画点速度,发现wxPython要快一个数量
级.这可能是因Tkinter不仅要调用Python还得用Tcl两个脚本语
言之故.对于PyQt,俺没能在俺的Mandrake7.2上编译成功,所以就
没学它了, 不过据说也拥有稍小于wxPython的用户群;PyGtk目前
还不如wxPython和PyQt成熟. 下面俺就略说一下Tkinter.就入门
而言, Tkinter还是值得一瞄的.而且网上有很多关于它的入门介
绍, 如:
http://www.pythonware.com/library/an-introduction-to-tkinter.htm
http://www.python.org/doc/life-preserver/
也正好看到OSO就有<<Teach Yourself Python>>的源码下载,其后
面几章就是Tkinter的样例, 其中一个就是画Mandelbrot集的.
a)Tk与Tkinter对照:
Tk ==> Tkinter
button .b ==> b=Button() #在根窗口中定义一个按钮
button .panel.b ==> b=Button(panel) #在面板中定义一个按钮.
button .b -fg red ==> b=Button(fg="red") #设置前景色
.b configure -fg red ==> b["fg"]=red #部件产生后再配置
==> b.config(fg="red") #第二种方法
pack .b -side left ==> b.pack(side="left") #列入右边并显示
b)最简单的例子 (一个窗口中含字串: Hello, world!)
from Tkinter import *
root = Tk() #产生一个根窗口
l = Label(root, text="Hello, world!")# 产生一个标识
l.pack()
root.mainloop() #进入主循环, 有事件则运行, 无事就等着
c)仍是十分简单的例子(一个窗口中两个按钮:Quit和Hello)
from Tkinter import * #引入Tkinter模块
class App: #定义一个类
def __init__(self, master): #类的构造器, 相当于C++的constructor
frame = Frame(master) #产生一个框架
frame.pack()
button = Button(frame, text="QUIT", fg="red", command=frame.quit)
button.pack(side=LEFT)
hi_there = Button(frame, text="Hello", command=self.say_hi)
#self.say_hi是调用类的函数 say_hi()
hi_there.pack(side=LEFT)
def say_hi(self):
print "hi there, everyone!"
root = Tk()
app = App(root) #上面__init__有两个参数, self只是对象
root.mainloop()
上面b), c)取自:
http://www.pythonware.com/library/tkinter/introduction/
因b)简单, c)介绍了类的用法. 在c)中俺将它原来的self.button
和self.hi_there改成了button和hi_there, 因为不会在类的其它
地方调用这两个器件. 俺刚才试过, 没问题的.
另外,OSO发文时好象不能发图片.俺自己倒是省了点事.读者可以到
上面所给地址去看程序运行结果, 及更多内容. 俺这里只是想给大
家一个初始印象.
顺便说一下,俺本来还想给出wxPython的两个例子,幸好到OSO上的
搜索了一下, 原来limodou先生已经将O'Reilly书:
<<Python Programming on Win32>>
中有关wxPython的内容全译了:
http://www.oso.com.cn/read_article.php?article_id=4134
而且是最近才译的, 看来 "英雄所见略同", :-) 不过俺发现他文章
样例程序中的行头空格全没了 --- 这样的Python程序是无法运行的.
也许是浏览器将之当作Html文件了.所以推荐其原网页供各位下载样
例源码:
http://www.oreilly.com/catalog/pythonwin32/chapter/ch20.html
(其实oreilly.com上仅仅给了<<Win32上的Python编程>>中的两章作
样子,但幸运的是其中就有这章GUI编程.) wxPython.org上的简介还
没有O'Reilly上的详细. wxPython的作者及wxWindows的几位一起开
了个wxpros.com, 来提供支持服务(如培训,付费答疑等), 愿其成功,
或至少能供养肚子继续发展wxPython, :-)
杂类
这里俺想补充几点俺的前面四篇中尚未提及但仍很有用的地方. 下面
将要出现的 ...是Python的第二提示符, 表示继续一个不完整的命令
*)Python中的每个变量都是对象 --- Python特有的对象, 并不一定
都是 "面向对象的编程" 中的对象
*)第一有效行(非解释行), 其行首必须没有空格(在Python中, 表格
键Tab 缺省是等于8个空格.)
*)续行可以用行末的 '\', 注意其后必需是回车/换行; 对于包在大,
中, 小括号中的若干行, 系统都缺省作续在一起的一行. 但不能把
一个变量名分开放在两行上. 如:
>>> score = {'xah':59,
... 'you':99}
>>>
>>> score\
... ['xah']
59
>>> scor\
... e['xah'] #错误
File "<stdin>", line 2
e['xah']
^
SyntaxError: invalid syntax
>>>
*)交互式用法中的下划线: _ , 是上面一行命令运行的结果. 如:
>>> 3+5
8
>>> _ * 7
56
*)屏幕输出
在print最后加一逗号, 就不会自动输出'\n', 而输出一空格;
也可用格式符:
>>> print 'a'; print 'b'
a
b
>>> print 'a',; print 'b' #第一句后加了一个逗号
a b
>>> print '%x %s' % (11, 'abc') #多变量时须用小括号括起,见下面: Tuple
b abc
再重提一下, 包在匹配的 三个单引号或三个双引号之间的字
串, 可以是多行, 相当于HTML中的<PRE>和</PRE>, 即原样在
屏幕上输出. 也可对它们用格式符:
>>> a = ''' pytho
... n is %s!''' % 'great'
>>> a
' pytho\012n is great!' #Python用8进制显示控制字符: \n == \012
>>> print a
pytho
n is great!
>>>
Python 2.0版之后就可能用 >>stderr 来打印到标准错误输出:
>>> from sys import stderr
>>> print >> stderr, 'ok'
ok
2.0版之前好象是用文件形式: stderr.write('ok')
*)字串变数字, 数字变字串:
>>> int('123')
123
>>> float('123')
123.0
>>> eval('123') #随所给字串, 既可产生整数, 也可浮点数
123
>>> str(123) #数字到字串
'123'
>>> `123` #反向单引号, 还可用函数: repr(数字变量)
'123'
*)屏幕输入:
字串输入: s = raw_input(提示字串)
数字输入: x = input(提示字串) #相当于: eval(raw_input())
*)字串按空格或其它用户定义的分隔符来分隔.
Python 2.0版以后的, 可以用:
>>> a='123 321 456'
>>> a.split()
['123', '321', '456']
>>> a.split('2')
['1', '3 3', '1 456']
>>> 'AA'.join( a.split('2') ) #按分隔符'AA'将字串数列合并
'1AA3 3AA1 456'
但2.0(或至少1.6 ?)以前必须要引入string模块: (也即2.0
将原本在string模块中的不少函数并入字串的方法中去了,
但不是全部):
>>> from string import split, join
split(a,'2')
['1', '3 3', '1 456']
>>> join ( split(a,'2'), 'AA') #同上, 但调用了函数
'1AA3 3AA1 456'
*)交互式下可以用dir()来看从模块中引入了什么函数与变量:
>>> import math
>>> dir(math)
['__doc__', '__file__', '__name__', 'acos', 'asin',
'atan', 'atan2', 'ceil', 'cos', 'cosh', 'e', 'exp'
, 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp
', 'log', 'log10', 'modf', 'pi', 'pow', 'sin', 'sin
h', 'sqrt', 'tan', 'tanh']
看函数/模块的说明(函数/模块中的第一行字串, 或多行位于
成对的''', """之间):
>>> import math
>>> print math.__doc__
This module is always available. It provides access to the
mathematical functions defined by the C standard.
>>> print math.sin.__doc__
sin(x)
Return the sine of x.
>>>
*)文件
打开:
f = open("My.py") #只读
f = open("My.py", "r") #只读
f = open("My.py", 'r+b')#可读可写, 二进制文件
f = open("tmpFile", 'w')#只写
读:
s = f.read(字节数) #读给定字节数的内容
text = f.read() #读整个文件, 得到一字串
line = f.readline() #读一行(含换行符: '\n')
lines = f.readlines() #读整个文件, 得到字串数列
#lines[-1]是最末一行(含'\n'), 等等
写:
f.write('AAAbbb\n') #写一个字串
f.writelines(lines) #写字串所组成的数列
关闭:
f.close()
*)lambda函数
来自Lisp/Scheme, 好象是只能有一个执行句子. 可能主要是
用来简写一个函数的定义.
>>> f = lambda a, b, c : (a + b ) * c
>>> f(1,2,3)
9
看样子它有点类似于C/C++中的:
#define max(A, B) (A)>(B) ? (A) : (B)
*)空白类可以来作C中的"struct"功能:
>>> class My: pass
... #其中pass是不执行任何命令. 大概是由于分号在Python
... #中不太起作用, 所以引入"pass". 而C中就可以用:
... # for (;;);
... #来"等你等到天尽头".
...
>>> xah = My()
>>> xah.birthDay = 1
>>> xah.birthYear = 3000
>>> xah.birthYear
3000
>>>
*)错误处理
通常Python若出错误, 即会自动退出. 但你可以用
try : 可能出错语句
except 特定错误 : 出错后要执行的命令
来处理. 如:
>>> 1/0 #除0错误
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ZeroDivisionError: integer division or modulo by zero
>>> try: 1/0
... except ZeroDivisionError:
... print "ok"
...
ok
*)Tuple, 俺在<<英华大字典>>上都没找到其译文. 马苏安的星际
译王将之译为"元组". 英文解释似乎也很强调它的有序性.这里
俺就暂用"元组".
Python的元组是用小括号括起来的变量, 常数, 函数等对象的组
合, 虽然有时候小括号可以省略. 如俺以前给出过:
total, i = 0, 0
其实就是元组赋值:
(total, i) = (0, 0)
*)字串和元组皆是一经产生就不可再变更, 只能另赋新值. 这也是
元组不同数列之处. 数列和字典皆可在产生之后变更. 如:
>>> s="abc"
>>> s[2] = 'D' #错误:
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: object doesn't support item assignment
>>> t = (3, 5)
>>> t[0] = 4 #错误
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: object doesn't support item assignment
但可以用其片段来组成一个另变量:
>>> s='abc'
>>> s2 = s[1:-1] + 'd'
>>> s2
'bd'
>>> s='def'
>>> s
'def'
元组中的可变更变量也可另赋值:
>>> x, y = 3, 5
>>> a=(x,y)
>>> a
(3, 5)
>>> y=4
>>> a
(3, 5)
>>> x,y=3, [4,5]
>>> z=x, y
>>> z
(3, [4, 5])
>>> y[0] = 2
>>> z
(3, [2, 5])
>>>
*)赋值,
跟能常所说的(如C/C++)赋值有些不一样.
变量赋给变量时, 只是增加了对同一对象的参考(Reference),
而不产生新变量. 如:
>>> l=[3,4]
>>> l2=l
>>> l[0]=-1
>>> l
[-1, 4]
>>> l2
[-1, 4]
而俺发现用l2 = l[0:]就不一样:
>>> l=[3,4]
>>> l2=l[0:]
>>> l[0]=-1
>>> l
[-1, 4]
>>> l2
[3, 4]
但对不可变更的对象, 因其不可变更, 或只能另赋新值, 所以
只表现为常见的"赋值即产生新对象"的样子:
>>> s='abc'
>>> ss = s
>>> ss
'abc'
>>> s='345'
>>> s
'345'
>>> ss
'abc'
本节结语: 希望大家不要被俺绕糊涂了, 俺只是想提供一些Python
与通常的语言, 如C/C++, 相比而不同之处. 总的来说, Python还是
蛮好用的. wxPython作者, 罗宾 . 邓恩 (Robin Dunn) 就在网上说,
他个人习惯是一切编程皆用Python; 即使真需要速度, 他也将C/C++
编成Python模块.
到此为止对Python还很感兴趣的同志, 可以去当Python的库参考了.
(mpage可以4合1, 加上正反面打印, python.org上的400页库参考
你50张纸就行了, 只要你视力不是太弱可以看小号字体, :-) )
-
pygtk 的图象编程
俺最近又稍学了点pygtk, 贴出来给大家分享.
俺去学pygtk的原因是, 俺发现在俺的机子上pygtk比wxpython在
启动时要几乎快上一倍(1-2秒相对于2-5秒); 并且俺发现一个简
单的按钮显示, wxpython的程序运行起来要占约10-12M内存, 而
pygtk的只要约5-6M.
后来俺就到wxpython的用户邮件列表上发问, 那里的人还很热心
地作了解释, 说启动速度和内存是因为UNIX下的wxGtk在是对Gtk
库进行包装的结果, 并说启动之后的执行速度二者应无显蓍差别.
wxWindows故而拥有很好的移植性. 还有人指出了二者其它异同.
大意是pygtk还可以使用主题色彩配置(themes), 而且gnomepy还
可以使用libglade库来简化很多编程任务; 但wxpython的小器件
(widget)还是要比目前的pygtk要丰富. 关于Gtk在MS Windows上
的运行, 有人说很稳定了, 也有人说每5分钟死一次机. 另外,俺
还瞄了瞄二者用户列表上的帖子数量, 发现wxpython的约为pygtk
的两倍左右.
所以总的看来, 还是各有千秋. 大家不妨也来瞄瞄pygtk.
Gtk+与Python的结合早就有人捣弄了, 不过目前最正统还是
James Henstridge做的,看网址他好象是澳大利亚人. pygtk的
主页在:
http://www.daa.com.au/~james/pygtk/
而在这里有pygnome的入门简介:
http://laguna.fmedic.unam.mx/~daniel/pygtutorial/
俺下面就取其中的两个例子(也是pygtk源程序中examples/simple
目录中的两个程序)稍作解释.
pygtk目前的稳定版是0.6.6; 作者说: 别看它版本还不高, 里
面的小器件还真不少, Gtk+ 1.2的玩意差不多全包括了. 咱这
就过来瞧一瞧.
pygtk有两种实现. 最老早的是基于C语言的函数调用形式, 这
倒与Gtk+本身很相近; 后来采用了面向对象的形式, 感觉要简
洁不少. 请看:
1)"世界好!"的C语言调用形式
(来自pygtk源程序中的examples/simple/hello1.py)
#!/usr/bin/env python #让程序可执行
from _gtk import * #引入pygtk的C函数模块, gtk前有下划线
from GTK import * #引入常用变量模块
def hello(*args): #函数定义: 屏幕显示"世界好"
print "Hello World"
gtk_widget_destroy(window)
def destroy(*args): #退出函数定义
gtk_widget_hide(window)
gtk_main_quit()
gtk_init() #Gtk初始化
window = gtk_window_new(WINDOW_TOPLEVEL) #产生一个窗口
gtk_signal_connect(window, "destroy", destroy) #退出信号连接
gtk_container_set_border_width(window, 10) #边界宽度设定
button = gtk_button_new_with_label("Hello World")#产生一个按钮
gtk_signal_connect(button, "clicked", hello) #鼠标点击传到函数
gtk_container_add(window, button) #将按钮加入到窗口中
gtk_widget_show(button) #显示按钮
gtk_widget_show(window) #显示窗口
gtk_main() #等待鼠标动作
2)"世界好!"的面向对象的形式
(来自pygtk源程序中的examples/simple/hello2.py)
#!/usr/bin/env python
from gtk import * #引入pygtk的面向对象的模块, gtk前无下划线
def hello(*args):
print "Hello World"
window.destroy()
def destroy(*args):
window.hide()
mainquit()
window = GtkWindow(WINDOW_TOPLEVEL) #产生一个窗口
window.connect("destroy", destroy) #退出信号连接
window.set_border_width(10) #边界宽度设定
button = GtkButton("Hello World") #产生一个按钮
button.connect("clicked", hello) #鼠标点击传到函数
window.add(button) #将按钮加入到窗口中
button.show() #显示按钮
window.show() #显示窗口
mainloop() #等待鼠标动作
===========
大家是不是也觉得第二种方法要简洁 ? pygtk的作者好象也是推荐
大家用第二种方式. 对大一点的程序, 照样可以用类(class)来把
它表达的很清楚.
俺就不多说了, 各位感兴趣的, 可以去上面的入门介绍中看看它们
运行的屏幕取像(screenshot), 再去当下pygtk的源程序装上(很小,
300k, 也很容易装上), 并运行一下它里面examples目录下的样例,
就会很了解pygtk能干什么活了. 当你自己想用它编简单任务时,直
接在其某个样例的基础进行加工是最省事的了.
相关推荐
Python 入门教程详细知识点总结 本文档提供了 Python 编程语言的详细入门教程,从零基础到精通,涵盖了 Python 的各个方面,包括语法、数据类型、函数、模块、面向对象、异常处理、网络编程和并发编程等。 第一章...
Python 入门教程 Python 是一种流行的设计语言,广泛应用于软件开发领域。本文档提供了一个简短的 Python 入门教程,涵盖了 Python 的基本概念、环境设置...通过学习 Python,可以让开发者更好地掌握软件开发的技巧。
资源名称:python基础教程至60课_python入门基础资料 内容简介:python基础教程至60课,这篇教程开始就为大家介绍了,为什么学习python,python有什么优点等,确实让你想快点学习python。为什么用Python作为编程...
本篇文章《Python入门网络爬虫之精华版》主要介绍了Python网络爬虫的基础知识,从抓取、分析到存储的三个主要方面,以及如何应对一些常见的反爬虫机制。此外,还提及了Scrapy这一流行的爬虫框架,并提供了一个参考...
小白的Python入门教程实战篇:网站+iOS App源码.zip小白的Python入门教程实战篇:网站+iOS App源码.zip小白的Python入门教程实战篇:网站+iOS App源码.zip小白的Python入门教程实战篇:网站+iOS App源码.zip小白的...
课程从零开始、幽默严谨、清晰全面,配有丰富的教学演示和插图、动画,是初学者学习Python程序设计的最佳入门教程。 本课程包含本系列的《基础篇》和《提高篇》,专注语法和编程思维,为后续《实战篇》深入各应用...
这篇“Python入门笔记”旨在帮助初学者快速掌握Python的基础知识,通过实践操作来加深理解。 首先,Python的语法特点是它的一大亮点。Python代码强调可读性,遵循“缩进决定代码块”的原则,避免了大括号带来的视觉...
这篇超详细的Python入门教程旨在帮助新手在1小时内快速掌握Python的基本概念和应用。 首先,Python的适用性体现在它能够轻松地处理各种任务,如系统管理、Web开发、科学计算等。在上述示例中,对比了使用Java和...
### Python入门基础篇 #### Python概述 Python是一种高级编程语言,以其简洁明了的语法著称,这使得Python成为一种易于阅读、易于维护且受到广大用户欢迎的语言。Python的设计哲学强调代码的可读性和简洁性,这也...
【Python入门教程】这篇教程是针对初学者设计的Python学习指南,主要涵盖了Python的基本概念、语法和编程思想。首先,我们需要了解Python编程的基础环境,包括安装Python解释器和选择一个文本编辑器,如emacs或...
【Python 入门指南】 Python 是一种高级编程语言,以其简洁明了的语法和强大的功能深受初学者和专业开发者的喜爱。这篇文档将带你逐步走进 Python 的世界。 首先,要开始学习 Python,你需要确保拥有一个合适的...
python 零基础学习篇-Python-第一章 Python入门导入1-3.mp3
这份文档旨在帮助想要学习Python爬虫的初学者,从入门到精通逐步提升自己的技能。以下是我们将要涵盖的主题: ## 入门篇 1. Python爬虫简介 2. Requests库的使用 3. Beautiful Soup库的使用 4. 爬虫实战:爬取百度...
通过本教程,读者可以从零基础开始学习Python语言,逐步深入到高级编程实战,掌握Python语言的核心技术和实践技能。 本教程的学习路线包括: 1. Python基础知识:包括基本语法、数据类型、控制结构、函数、模块等...
这个"小白的Python入门教程实战篇:网站+iOS App源码"很可能是一个面向初学者的教程资源,旨在帮助新手通过实践理解Python的基本概念和技能,同时涵盖网站开发和iOS应用的源码分析。 1. Python基础知识: Python以...
《笨办法学Python》是许多初学者入门Python编程的首选教材,因其简洁明了的教程风格深受喜爱。而“进阶篇”则是针对已经掌握了Python基础的读者,旨在帮助他们进一步提升技能,深入理解Python的高级特性以及在实际...
这个资料可能是一个简洁的Python入门教程,旨在帮助初学者快速掌握Python的基本语法和常用功能。它可能包括变量、数据类型、控制流、函数、文件操作等基本概念,是学习Python的起点。通过这个教程,新手可以快速...
要学习Python,你还需要一个文本编辑器来编写代码。 编程的本质是向计算机提供一系列指令,使其执行特定任务。以烹饪比喻,编程就像编写一份菜谱,但计算机无法直接理解和执行人类日常语言中的指令。因此,我们需要...
【Python入门到精通系列(入门篇)视频教程】是一门专为有Linux Shell基础的运维人员和希望提升自动化运维能力的学员设计的课程。课程旨在帮助学员深入理解Python语言,将其应用于企业的日常数据分析和运维系统管理,...