Time模块:
--------------------------
time() #以浮点形式返回自Linux新世纪以来经过的秒数。在linux中,00:00:00 UTC,

January 1, 1970是新**49**的开始。
>>> time.time()
1150269086.6630149
>>> time.ctime(1150269086.6630149)
>>> 'Wed Jun 14 15:11:26 2006'

time.ctime([sec])#把秒数转换成日期格式,如果不带参数,则显示当前的时间。

>>> import time
>>> time.ctime()
>>> 'Wed Jun 14 15:02:50 2006'
>>> time.ctime(1138068452427683)
'Sat Dec 14 04:51:44 1901'
>>> time.ctime(os.path.getmtime('E:\\untitleds.bmp'))
'Fri Sep 19 16:35:37 2008'

>>> time.gmtime(os.path.getmtime('E:\\untitleds.bmp'))
time.struct_time(tm_year=2008, tm_mon=9, tm_mday=19, tm_hour=8, tm_min=35,

tm_sec=37, tm_wday=4, tm_yday=263, tm_isdst=0)

将一个文件的修改时间转换为日期格式(秒 转 日期)
>>> time.strftime('%Y-%m-%d %X',time.localtime(os.path.getmtime

('E:\\untitleds.bmp')))
'2008-09-19 16:35:37'

#定时3秒。
>>> time.sleep(3)

TIME模块参考:
---------------------------------
#取一个文件的修改时间
>>> os.path.getmtime('E:\\untitleds.bmp')
1221813337.7626641

变量
timezone 通用协调时间和本地标准时间的差值,以秒为单位。
altzone 通用协调时间和本地夏令时的差值
daylight 标志,本地时间是否反映夏令时。
tzname (标准时区名,夏令时时区名)
函数
time() 以浮点数返回纪元至今以来的秒数。
clock() 以浮点数返回CPU开始这个process的时间,(或者至上次调用这个函数的时

间)
sleep() 延迟一段以浮点数表示的秒数。
gmtime() 把以秒表示的时间转换为通用协调时序列
localtime() 把秒时转换为本地时序列
asctime() 将时间序列转换成文本描述
ctime() 将秒时转换成文本描述
mktime() 将本地时序列转换成秒时
strftime() 以指定格式将序列时转为文本描述
strptime() 以指定格式从文本描述中解析出时间序列
tzset() 改变当地时区值

DateTime模块
----------------------------
datetime 将日期转化为秒
-------------------------------------
>>> import datetime,time
>>> time.mktime(datetime.datetime(2009,1,1).timetuple())
1230739200.0

>>> cc=[2000,11,3,12,43,33] #Attributes: year, month, day, hour, minute,

second
>>> time.mktime(datetime.datetime(cc[0],cc[1],cc[2],cc[3],cc[4],cc

[5]).timetuple())
973226613.0

将秒转换为日期格式
>>> cc = time.localtime(os.path.getmtime('E:\\untitleds.bmp'))
>>> print cc[0:3]
(2008, 9, 19)

DateTime示例
-----------------
演示计算两个日期相差天数的计算
>>> import datetime
>>> d1 = datetime.datetime(2005, 2, 16)
>>> d2 = datetime.datetime(2004, 12, 31)
>>> (d1 - d2).days
47

演示计算运行时间的例子,以秒进行显示
import datetime
starttime = datetime.datetime.now()
#long running
endtime = datetime.datetime.now()
print (endtime - starttime).seconds

演示计算当前时间向后10小时的时间。
>>> d1 = datetime.datetime.now()
>>> d3 = d1 + datetime.timedelta(hours=10)
>>> d3.ctime()

其本上常用的类有:datetime和timedelta两个。它们之间可以相互加减。每个类都有一

些方法和属性可以查看具体的值

3)glob
可以使用简单的方法匹配某个目录下的所有子目录或文件,用法也很简单。
3.1 glob.glob(regression) 返回一个列表
3.2 glob.iglob(regression) 返回一个遍历器
这个模块简单好用,强力推荐。

python 模块之----RE模块(转) 不指定

zeus , 2010/03/14 00:58 , Python , Comments(0) , Reads(363) , Via Original
1. 9.7 正则表达式与 re 模块

一个正则表达式就是一个用来表示某种模式的字符串。它能帮助你方便的检查一个字符串是否与某种模式匹配。

re 模块使 Python 语言拥有全部的正则表达式功能。 compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。 re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。

要精通正则表达式并不容易,而且这本书的主题也不是正则表达式。 本节的目的是教会你在 Python中使用正则表达式。如果要全面的了解正则表达式,我推荐Jeffrey Friedl写的《Mastering Regular Expressions》这本书。这本书全面透彻的讲解了正则表达式的方方面面。

1.1. 9.7.1 模式字符串语法

模式字符串使用特殊的语法来表示一个正则表达式:

字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。

多数字母和数字前加一个反斜杠时会拥有不同的含义。

标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。

反斜杠本身需要使用反斜杠转义。

由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 r'\t',等价于'\\t')匹配相应的特殊字符。

表 9-2 列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。本节后面会提到这些可选的标志。

表 9-2 正则表达式模式语法

元素 含义
. 匹配除换行外的任意字符(如果 DOTALL 则连换行也匹配)
^ 匹配字符串开始(如果MULTILINE,也匹配换行符之后)
$ 匹配字符串结束(如果MULTILINE,也匹配换行符之前)
* 匹配0个或更多个由前面的正则表达式定义的片段,贪婪方式(尽可能多的匹配)
+ 匹配1个或更多个由前面的正则表达式定义的片段,贪婪方式
? 匹配0个或1个由前面的正则表达式定义的片段,贪婪方式
*? , +?, ?? 非贪婪版本的 *, +, 和 ? (尽可能少的匹配)
{m,n} 匹配 m 到 n 次由前面的正则表达式定义的片段,贪婪方式
{m,n}? 匹配 m 到 n 次由前面的正则表达式定义的片段,非贪婪方式
[...] 匹配方括号内内的字符集中的任意一个字符
| 等于 或
(...) 匹配括号内的表达式,也表示一个组
(?iLmsux) 设置可选参数的另类方式,不影响匹配
(?:...) 类似 (...), 但是不表示一个组
(?P...) 类似 (...), 但该组同时得到一个 id,可以在后面的模式中引用
(?P=id) 匹配前面id组匹配的东西
(?#...) 括号内的内容仅仅是注释,不影响匹配
(?=...) Lookahead assertion; matches if regular expression ... matches what comes next, but does not consume any part of the string
(?!...) Negative lookahead assertion; matches if regular expression ... does not match what comes next, and does not consume any part of the string
(?<=...) Lookbehind assertion; matches if there is a match for regular expression ... ending at the current position (... must match a fixed length)
(? \number 匹配先前匹配过的组(通过序号,组自动从1-99编号)
\A 匹配字符串开始
\b 匹配单词边界
\B 匹配一个空串(非单词边界)
\d 匹配任意数字
\D 匹配任意非数字
\s 匹配任意空白字符
\S 匹配任意非空字符
\w 匹配字母数字
\W 匹配非字母数字
\Z 匹配字符串结束
\\ 匹配反斜杠

1.2. 9.7.2 常用正则表达式

'.*' 作为一个正则表达式片段表示 "任意个数(0或更多个)的任意字符(除换行外)"。也就是说, '.*' 匹配一个字符串中的任意子串,包括空串。

'.+' 与'.*'类似,不过它不包括空串。举例来说:

'pre.*post'

匹配一个字符串含有'pre' ,后面跟着一个 'post',中间可以隔着别的字符,也可以不隔着。 (举例来说, 它匹配 'prepost' 和 'pre23post')。

而 'pre.+post' 仅匹配 'pre' 和 'post' 之间有其它字符相隔的情况。(举例来说, 它匹配 'pre23post' 但不匹配 'prepost')。

要强制一个模式仅匹配由 'post' 结尾的字符串,用 \Z 结束这个模式。就象下面这样:

r'pre.*post\Z'

匹配 'prepost', 但不匹配 'preposterous'.

另一个经常用的模式是 \b, 它匹配单词边界. 如果你打算匹配单词 'his' 而不是 'this' 或 'history', 使用下面的正则表达式:

r'\bhis\b'

匹配以 'her' 开头的子串,使用:

r'\bher'

匹配以 'its' 结尾的子串,使用:

r'its\b'

匹配以 'her' 开头的任意单词:

r'\bher\w*'

匹配以 'its' 结尾的任意单词:

r'\w*its\b'

1.3. 9.7.3 字符集合

中括号 ([字符列表]) 用来表示字符集合. 可以用连字符 (-) 来表示连续的数字或字母。最后一个字符也包括在字符集合内,这与 Python range函数不同。中括号内的特殊字符代表他们本身, 除了 \, ], 和 - 之外, 这几个字符你必须转义后才可以代表其本身(通过在其前面放一个反斜线).一个字符集合内,你可以使用转义字符所表示的字符类,如 \d 或 \S 等.不过字符集合内的 \b 表示一个退格字符( backspace ), 而不是一个单词边界. 如果一个字符集合里的第一个字符是尖号 (^), 这个集合就是反集合,也就是说.这个集合匹配尖号后面的字符之外的任何字符.

一个常用集合用来匹配单词(字母,连字符或省略符(单引号)):

r"[a-zA-z'\-]+"

连字符前的转义反斜框在此处不是必需的,因为连字符所在位置使它不会具有歧义性.不过还是建议你一直对其使用转义符号,这会使你的模式字符串可读性更佳.

1.4. 9.7.4 可选择的匹配

竖线 (|) 表明竖线两边的匹配可以任选其一, 具有较低的优先级。. 如果不使用括号, | 则对其两边的整个模式起作用,直到遇到字符串起始或结束或另一个 | 符号为止.一个模式可以由任意个由 | 符号连接的子模式组成.要匹配一个这样的表达式,第一个子模式首先尝试匹配,如果匹配成功,其它的就被跳过.否则就尝试第二个,...第三个.... | 既是贪婪的又是非贪婪的,因为它根本不关心匹配长度.

如果你有一个单词的列表 L , 匹配任意单词的正则表达式就是:

'|'.join([r'\b%s\b' % word for word in L])

如果 L 的元素是常规字符串,而不仅仅是单词, 你需要用 re.escape(本章后面会有详述) 来转义它们. 如果你不需要 \b 单词边界,那么下面这个正则表达式就能满足你的需要:

'|'.join(map(re.escape,L))

1.5. 9.7.5 分组

正则表达式可以包含0至99个分组(允许任意个,但只有前99个被支持)。通常模式字符串中的一对未转义的小括号表示一个分组。元素 (?P...) 也表示一个分组,不同的是它还给这个分组指定了一个名字, id, 可以是任意的 Python 标识符。所有的分组,命名的或未命名的,均被从左至右编号( 1 至 99), 组号 0 表示整个正则表达式。

对一个字符串的任意正则表达式匹配, 每个分组匹配一个子串 (也可能是一个空串)。 当一个正则表达式使用 | 时, 某些分组可能不匹配任何子串,尽管整个正则表达式是匹配的。当一个分组的匹配是一个空串时,我们称这种情形为该分组没有参与匹配。 举例来说:

r'(.+)\1+\Z'

该模式匹配任意非空子串的两个或更多个重复。(.+) 匹配一个非空子串 (任意字符任意个), 并且定义了一个分组。 \1+ 部分匹配1至更多次这个分组的重复。\Z 将匹配限制只允许发生在字符串的结尾。

1.6. 9.7.6 选项

除了在 re 模块的 compile 函数中提供 flags 选项参数之外,在 (? 和 ) 之间使用"iLmsux" 中的一个或多个字母能让你可以在模式字符串中设置正则表达式选项。不论哪种方式设置的选项,都是针对整个正则表达式的。为了清晰起见,选项通常总是放在模式的开头。如果使用选项x,则选项必须放置在模式首部,因为x选项影响Python解析模式的方式。

显式的使用选项参数比起将选项参数放在模式字符串中具有更好的可读性。函数 compile 的 flags 参数是一个整数, 通过对re模块中提供的属性中的一个或几个进行 '按位或' 运算得来。 (with Python's bitwise OR operator, |). 为了书写方便,每个属性都有一个简称 (一个大写字母)和一个全名 (一个全大写的标识符,具有更好的可读性)。

I 或 IGNORECASE 匹配忽略时大小写

L 或 LOCALE 让 \w, \W, \b, 和 \B 由当前区域设置决定

M 或 MULTILINE 特殊符号 ^ 和 $ 除了匹配字符串开始和结尾,也匹配每行的开始和结尾 (换行符之后/之前)

S 或 DOTALL 特殊字符 . 匹配任意字符,包括换行符

U 或 UNICODE \w, \W, \b, 和 \B 由Unicode字符集决定

X 或 VERBOSE 忽略模式字符串中的空白字符, 除非被转义的空白或空白位于字符集合内(中括号内)。该方式允许用 # 字符添加注释直至行尾。

举个例子,下面用三种不同的方式通过 compile 函数生成了相同的三个正则表达式对象(均与不区分大小写的'hello'模式匹配):
Toggle line numbers Toggle line numbers

1 import re
2 r1 = re.compile(r'(?i)hello')
3 r2 = re.compile(r'hello', re.I)
4 r3 = re.compile(r'hello', re.IGNORECASE)

第三种方式清晰易读,容易维护,尽管它写起来麻烦一点点。注意虽然在这里使用原始字符串不太必要(没有使用转义字符),不过仍然推荐你一直在书写模式字符串时使用原始字符串。

选项 re.VERBOSE (或 re.X) 允许你通过在模式字符串中添加适当的空白和注释来使得正则表达式更容易阅读和维护。复杂的模式可以写成多行,并且能够为每一行添加注释。因此在这种模式你最好使用三引号字符串来书写模式字符串。举例来说:

repat_num1 = r'(0[0-7]*|0x[\da-fA-F]+|[1-9]\d*)L?\Z'
repat_num2 = r'''(?x) # 该模式用来匹配整数
(0 [0-7]* | # 八进制: 前导 0, 0+ 个八进制数字
0x [\da-f-A-F]+ | # 十六进制: 0x, 1+ 十六进制数字
[1-9] \d* ) # 十进制: 前导数字(非0), 0+ 十进制数字
L?\Z # 可有可无的L, 位于字符串结尾
'''

该例子中的两个模式是完全同义的。但是第二个因为添加了注释并且合理的使用了空白,因此具有更好的可读性和可维护性。
1.7. 9.7.7 Match VS Search

到目前为止,我们已经学会了使用正则表达式来匹配字符串。如果用 match方法,正则表达式模式 r'box' 匹配字符串 'box' 和 'boxes', 但是不匹配 'inbox'. 也就是说,正则表达式对象的 match 方法总是默认匹配从字符串的起始位置开始匹配。就象模式字符串的第一个元素是 \A 一样。

通常,你可能关心发生在字符串的任意位置的匹配,而不是仅发生在字符串首部的匹配。Python管这种操作叫做 Search ,这是为了和 match 有所区别而取的新术语。要进行 search ,你只需要简单的使用正则表达式对象的 search 方法就可以了。看下面的例子:
Toggle line numbers Toggle line numbers

1 import re
2 r1 = re.compile(r'box')
3 if r1.match('inbox'): print 'match succeeds'
4 else print 'match fails' # prints: match fails
5 if r1. search('inbox'): print 'search succeeds' # prints: search succeeds
6 else print 'search fails'

1.8. 9.7.8 字符串开始和结束

\A and \Z 分别用来表示字符串的开始和结束。传统上使用 ^ 代表字符串开始, $ 代表字符串结束. 在非多行方式下,^ 等于 \A, $ 等于 \Z。(模式串中没有 ?m 并且没有使用标志 re.M 或 re.MULTILINE进行编译).对一个多行正则表达式对象来说, ^ 代表任意行的开始 (可能是字符串开始,也可能是一个换行符之后). 类似的, $ 代表任意行的结束(可能是字符串的结束,也可能是一个换行符之前). \A 和 \Z 无论是否多行方式,总是严格匹配字符串的开始和结束。举例来说:下面的代码检查一个文件中是否有以数字结束的行。
Toggle line numbers Toggle line numbers

1 import re
2 digatend = re.compile(r'\d

模式 r'\d\n' 几乎与r'\d$'同义, 但是当一个文件以数字却没有回车结尾时,匹配将会失败。

1.9. 9.7.9 正则表达式对象

正则表达式对象 r 拥有下列只读属性, 这些属性详细描述了 r 是被如何创建出来的。 (通过模块 re 中的 compile 函数,见后文):

1.9.1. flags

传递给 compile 函数的 flags 参数, 如果省略了 flags 参数则为 0

1.9.2. groupindex

一个字典,它的 key 是通过元素(?P)定义的组的名字; 相应的值则是该组的序号。

1.9.3. pattern

编译 r 使用的模式字符串

这些属性让你很容易的重新得到该对象被编译时使用的模式字符串和参数,再也不需要将它们保存到一个单独地方了了。

正则表达式对象 r 同样提供了很多方法来定位一个字符串中的正则表达式的匹配, 以便进行替换或其它操作,匹配通常由特殊对象表示, 9.7.10节会详细介绍.

1.9.4. findall 方法

r.findall(s)

当 r 没有分组时, findall 返回一个字符串列表, 每个字符串都是 s 中不重叠的 r 的匹配. 下面的例子演示了如何打印出一个文件中的所有单词:
Toggle line numbers Toggle line numbers

1 import re
2 reword = re.compile(r'\w+')
3 for aword in reword.findall(open('afile.txt').read( )):
4 print aword

当 r 有一个分组时, findall 也返回一个字符串列表,列表中的每个字符串都是这个分组的匹配. 举例来说,如果你希望打印出所有的单词(不包括标点),你只需要在上面的例子里修改一个语句:

reword = re.compile('(\w+)\s')

当 r 有 n 个分组时 ( n > 1), findall 返回一个tuple的列表, 包括每一个不重叠的匹配. 每个tuple 有 n 个元素, 每个元素对应一个分组. 下面的例子打印出每行的第一个和最后一个单词(当然是匹配至少有两个单词的行).
Toggle line numbers Toggle line numbers

1 import re
2 first_last = re.compile(r'^\W*(\w+)\b.*\b(\w+)\W*

1.9.5. match 方法

r.match(s,start=0,end=sys.maxint)

当匹配时,返回一个 match 对象,否则返回 None. 注意这个匹配严格的从字符串的 start 位置开始. 要在整个字符串中向前搜索匹配,使用 r.search 而不是 r.match. 下面的例子演示了如何打印出一个文件中所有以数字开头的行:
Toggle line numbers Toggle line numbers

1 import re
2 digs = re.compile(r'\d+')
3 for line in open('afile.txt'):
4 if digs.match(line): print line,

1.9.6. search 方法

r.search(s,start=0,end=sys.maxint)

如果匹配成功,返回一个匹配最左边子串的 match 对象,否则返回 None.下面的例子演示了如何打印出含有数字的行:
Toggle line numbers Toggle line numbers

1 import re
2 digs = re.compile(r'\d+')
3 for line in open('afile.txt'):
4 if digs.search(line): print line,

1.9.7. split 方法

r.split(s,maxsplit=0)

返回一个该匹配分隔的子串列表.举例来说,要排除一个字符串中所有的 'hello' 不区分大小写,可以这样:
Toggle line numbers Toggle line numbers

1 import re
2 rehello = re.compile(r'hello', re.IGNORECASE)
3 astring = ''.join(rehello.split(astring))

如果 r 有多个分组,则分隔的规则就会象下面这样。下面这个例子只删除位于一个冒号(:)和数字之间的空白。
Toggle line numbers Toggle line numbers

1 import re
2 re_col_ws_dig = re.compile(r'(:)\s+(\d)')
3 astring = ''.join(re_col_ws_dig.split(astring))

这个例子可以说明更多问题:

>>> pat=r'(abc):(123)4(56)'
>>> r=re.compile(pat)
>>> s='aaabc:123456defghikabc:123456lll'
>>> r.split(s)
['aa', 'abc', '123', '56', 'defghik', 'abc', '123', '56', 'lll']

若 maxsplit 大于 0, 则至多进行 maxsplit 次分隔,剩下的部分则成为列表的最后一个元素。下面的例子只删除第一个匹配的'hello':

astring = ''.join(rehello.split(astring, 1))

1.9.8. sub 函数

r.sub(repl,s,count=0)

返回字符串s的一个拷贝,该串中的所有匹配均被替换成了 repl 。repl可以是一个字符串或一个可调用对象(函数或别的东西)。仅当不存在前一个匹配时,使用空的匹配(空串)替换. 当 count 大于 0 时, 只有前 count 个匹配被替换。若 count 等于 0, 所有的匹配都被替换. 下面的例子提供了删除目的字符串中第一次出现的 'hello' (不区分大小写)的另外一种方式:
Toggle line numbers Toggle line numbers

1 import re
2 rehello = re.compile(r'hello', re.IGNORECASE)
3 astring = rehello.sub('', astring, 1)

如果例子中的 sub 方法没有最后一个参数, 则例子中的字符串 astring 中的所有 'hello' 均被删除。

若 repl 是一个可调用对象, repl 必须接受且仅接受一个 match 对象做为参数,并返回用来替换匹配的字符串。 sub 调用 repl, 并提供给 repl 一个合适的 match-object 参数, repl则为每个匹配返回一个替换值。还是举个例子表述的清楚,要将所有首字母为'h',末字母为 'o' 的匹配单词转化为大写,你可以这么做:
Toggle line numbers Toggle line numbers

1 import re
2 h_word = re.compile(r'\bh\w+o\b', re.IGNORECASE)
3 def up(mo): return mo.group(0).upper( )
4 astring = h_word.sub(up, astring)

在你不需要对匹配进行替换而是需要对这些匹配进行更复杂的处理时,sub 方法非常有用. 下面这个例子展示了 sub 方法的使用,它用来对一个没有分组的正则表达式生成一个类似 findall 方法的函数.
Toggle line numbers Toggle line numbers

1 import re
2 def findall(r, s):
3 result = [ ]
4 def foundOne(mo): result.append(mo.group( ))
5 r.sub(foundOne, s)
6 return result

这个例子需要 Python 2.2 或更高, 不仅仅是因为它使用了嵌套作用域, 更大的原因是 Python 2.2 允许 repl 返回None并且视为其返回一个空串(). 而 Python 2.1则太轴,在Python2.1中,只允许 repl 返回一个字符串.

若 repl 是一个字符串而且它不是一个向后引用时, sub 使用 repl 自身作为替换.向后引用是一个 \g 形式的 repl 子串,这里 id 是 r 中一个分组的名字(由 r 中模式字符串中的 (?P) 建立), 或 \dd, 这里 dd 是一个或两个数字,代表一个分组的编号. 每个向后引用,不论是命名的还是编号的, 都被其所代码的匹配内容所替换.举例来说,下面这个将每个单词放入大括号中:
Toggle line numbers Toggle line numbers

1 import re
2 grouped_word = re.compile('(\w+)')
3 astring = grouped_word.sub(r'{\1}', astring)

1.9.9. subn 函数

r.subn(repl,s,count=0)

subn 与 sub 相同, 只是 subn 返回一个元组 (new_string, n) ,这里 n 是 subn 替换的数字.看这个例子, 要统计子串'hello'出现的次数,一个方法是:
Toggle line numbers Toggle line numbers

1 import re
2 rehello = re.compile(r'hello', re.IGNORECASE)
3 junk, count = rehello.subn('', astring)
4 print 'Found', count, 'occurrences of "hello"'

1.10. 9.7.10 Match 对象

正则表达式对象的 match 和 search 方法创建并返回 Match 对象. 当 repl 参数为可调用对象时, sub 及 subn 方法也会在幕后悄悄生成 Match 对象并使用.(在那种情况下一个相应的 match 对象被作为实参传递给 repl 对象.一个match 对象 m 支持以下属性:

pos 起始位置. 传递给 match 或 search 对象的开始位置参数(也就是字符串s开始匹配位置)

endpos 结束位置.传递给 match 或 search 对象的结束位置参数(也就是字符串s结束匹配位置)

lastgroup 最后匹配的分组的名字(或分组没有名字或根本没有匹配,返回None)

lastindex 最后匹配的分组的整数索引(从1开始). (如果没有匹配返回 None)

re 创建 m 对象的方法所属的正则表达式对象.

string 传递给方法 match, search, sub, 或 subn 的字符串 s

一个 match 对象也支持以下方法:

1.10.1. end, span, start 方法

m.end(groupid=0)

m.span(groupid=0)

m.start(groupid=0)

这些方法返回 m.string 中的由groupid 确定的分组所匹配的子串的定界索引.这里 groupid 可以是一个分组的编号或名字. 当匹配子串是 m.string[i:j] 时, m.start 返回 i, m.end 返回 j, m.span 返回 (i, j). 当分组没有匹配时, i 和 j 的值为 -1.

1.10.2. expand 方法

m.expand(s)

返回 s 的一个拷贝, 其中转义序列和向后引用以和 r.sub 同样的方式进行了了替换. 前一小节有详述.

1.10.3. group 方法

m.group(groupid=0,*groupids)

当以一个单一的 groupid 参数(一个分组编号或名字)调用时, m.group 返回匹配该分组的子串或 None(没有匹配时). 一个惯用的方式就是 m.group( ), 也就是 m.group(0), 返回整个匹配子串(group 编号 0 暗指整个正则表达式).

当以多参数的方式调用时, 每个参数必须是一个分组编号或分组名字. 这时 m.group 就返回一个tuple(每个元素对应一个参数), 元素的是匹配相应分组的子串或 None (未发生匹配时).

1.10.4. groups 方法

m.groups(default=None)

返回一个tuple,tuple的每个元素分别是模式中的分组。如果匹配失败,则返回 none.

1.10.5. groupdict 方法

m.groupdict(default=None)

返回一个 key 为表达式 r 中的命名分组名字的一个字典. 每个名字的值是相应的匹配子串,或者在未有匹配时 default 的值.

1.11. 9.7.11 模块 re 中的函数

模块 re 不仅提供了 9.7.6 节中的属性,它还提供了与正则表达式对象的每个方法功能相同的函数。(findall, match, search, split, sub, and subn), 这些函数的第一个参数就是模式字符串。显然这些函数内部也是将这个模式字符串编译为正则表达式对象后再处理的。通常显示的将模式字符串编译为正则表达式对象然后调用该对象的方式更好些,不过,对于某些模式的一次性使用,使用函数更方便一些。举例来说,统计'hello'在一个字符串中出现的次数(不区分大小写),象下面这样做:
Toggle line numbers Toggle line numbers

1 import re
2 junk, count = re.subn(r'(?i)hello', '', astring)
3 print 'Found', count, 'occurrences of "hello"'

象上面这种方式使用正则表达式,正则表达式选项必须内嵌在模式字符串内(例如在这个例子里的大小写不敏感选项,即(?i)),这是因为这些函数被设计成不接受标志选项参数。

模块 re 也提供了错误处理,当发生错误时会引发异常(通常都是模式字符串的语法错误)。 re模块还提供了两个另外的函数:

1.11.1. compile 函数

compile(pattern,flags=0)

解析模式字符串中的每一个语法元素,若无错误则创建并返回一个正则表达式对象。

1.11.2. escape 函数

escape(s)

返回一个字符串s的拷贝,不过s中的所有非字母数字字符在新串中均已被转义(在其前面添加反斜杠)。
, re.MULTILINE) 3 if re.search(open('afile.txt').read()): print "some lines end with digits" 4 else: print "no lines end with digits"

模式 r'\d\n' 几乎与r'\d$'同义, 但是当一个文件以数字却没有回车结尾时,匹配将会失败。

1.9. 9.7.9 正则表达式对象

正则表达式对象 r 拥有下列只读属性, 这些属性详细描述了 r 是被如何创建出来的。 (通过模块 re 中的 compile 函数,见后文):

1.9.1. flags

传递给 compile 函数的 flags 参数, 如果省略了 flags 参数则为 0

1.9.2. groupindex

一个字典,它的 key 是通过元素(?P)定义的组的名字; 相应的值则是该组的序号。

1.9.3. pattern

编译 r 使用的模式字符串

这些属性让你很容易的重新得到该对象被编译时使用的模式字符串和参数,再也不需要将它们保存到一个单独地方了了。

正则表达式对象 r 同样提供了很多方法来定位一个字符串中的正则表达式的匹配, 以便进行替换或其它操作,匹配通常由特殊对象表示, 9.7.10节会详细介绍.

1.9.4. findall 方法

r.findall(s)

当 r 没有分组时, findall 返回一个字符串列表, 每个字符串都是 s 中不重叠的 r 的匹配. 下面的例子演示了如何打印出一个文件中的所有单词:
Toggle line numbers

___FCKpd___5

当 r 有一个分组时, findall 也返回一个字符串列表,列表中的每个字符串都是这个分组的匹配. 举例来说,如果你希望打印出所有的单词(不包括标点),你只需要在上面的例子里修改一个语句:

___FCKpd___6

当 r 有 n 个分组时 ( n > 1), findall 返回一个tuple的列表, 包括每一个不重叠的匹配. 每个tuple 有 n 个元素, 每个元素对应一个分组. 下面的例子打印出每行的第一个和最后一个单词(当然是匹配至少有两个单词的行).
Toggle line numbers

___FCKpd___7

1.9.5. match 方法

r.match(s,start=0,end=sys.maxint)

当匹配时,返回一个 match 对象,否则返回 None. 注意这个匹配严格的从字符串的 start 位置开始. 要在整个字符串中向前搜索匹配,使用 r.search 而不是 r.match. 下面的例子演示了如何打印出一个文件中所有以数字开头的行:
Toggle line numbers

___FCKpd___8

1.9.6. search 方法

r.search(s,start=0,end=sys.maxint)

如果匹配成功,返回一个匹配最左边子串的 match 对象,否则返回 None.下面的例子演示了如何打印出含有数字的行:
Toggle line numbers

___FCKpd___9

1.9.7. split 方法

r.split(s,maxsplit=0)

返回一个该匹配分隔的子串列表.举例来说,要排除一个字符串中所有的 'hello' 不区分大小写,可以这样:
Toggle line numbers

___FCKpd___10

如果 r 有多个分组,则分隔的规则就会象下面这样。下面这个例子只删除位于一个冒号(:)和数字之间的空白。
Toggle line numbers

___FCKpd___11

这个例子可以说明更多问题:

___FCKpd___12

若 maxsplit 大于 0, 则至多进行 maxsplit 次分隔,剩下的部分则成为列表的最后一个元素。下面的例子只删除第一个匹配的'hello':

___FCKpd___13

1.9.8. sub 函数

r.sub(repl,s,count=0)

返回字符串s的一个拷贝,该串中的所有匹配均被替换成了 repl 。repl可以是一个字符串或一个可调用对象(函数或别的东西)。仅当不存在前一个匹配时,使用空的匹配(空串)替换. 当 count 大于 0 时, 只有前 count 个匹配被替换。若 count 等于 0, 所有的匹配都被替换. 下面的例子提供了删除目的字符串中第一次出现的 'hello' (不区分大小写)的另外一种方式:
Toggle line numbers

___FCKpd___14

如果例子中的 sub 方法没有最后一个参数, 则例子中的字符串 astring 中的所有 'hello' 均被删除。

若 repl 是一个可调用对象, repl 必须接受且仅接受一个 match 对象做为参数,并返回用来替换匹配的字符串。 sub 调用 repl, 并提供给 repl 一个合适的 match-object 参数, repl则为每个匹配返回一个替换值。还是举个例子表述的清楚,要将所有首字母为'h',末字母为 'o' 的匹配单词转化为大写,你可以这么做:
Toggle line numbers

___FCKpd___15

在你不需要对匹配进行替换而是需要对这些匹配进行更复杂的处理时,sub 方法非常有用. 下面这个例子展示了 sub 方法的使用,它用来对一个没有分组的正则表达式生成一个类似 findall 方法的函数.
Toggle line numbers

___FCKpd___16

这个例子需要 Python 2.2 或更高, 不仅仅是因为它使用了嵌套作用域, 更大的原因是 Python 2.2 允许 repl 返回None并且视为其返回一个空串(). 而 Python 2.1则太轴,在Python2.1中,只允许 repl 返回一个字符串.

若 repl 是一个字符串而且它不是一个向后引用时, sub 使用 repl 自身作为替换.向后引用是一个 \g 形式的 repl 子串,这里 id 是 r 中一个分组的名字(由 r 中模式字符串中的 (?P) 建立), 或 \dd, 这里 dd 是一个或两个数字,代表一个分组的编号. 每个向后引用,不论是命名的还是编号的, 都被其所代码的匹配内容所替换.举例来说,下面这个将每个单词放入大括号中:
Toggle line numbers

___FCKpd___17

1.9.9. subn 函数

r.subn(repl,s,count=0)

subn 与 sub 相同, 只是 subn 返回一个元组 (new_string, n) ,这里 n 是 subn 替换的数字.看这个例子, 要统计子串'hello'出现的次数,一个方法是:
Toggle line numbers

___FCKpd___18

1.10. 9.7.10 Match 对象

正则表达式对象的 match 和 search 方法创建并返回 Match 对象. 当 repl 参数为可调用对象时, sub 及 subn 方法也会在幕后悄悄生成 Match 对象并使用.(在那种情况下一个相应的 match 对象被作为实参传递给 repl 对象.一个match 对象 m 支持以下属性:

pos 起始位置. 传递给 match 或 search 对象的开始位置参数(也就是字符串s开始匹配位置)

endpos 结束位置.传递给 match 或 search 对象的结束位置参数(也就是字符串s结束匹配位置)

lastgroup 最后匹配的分组的名字(或分组没有名字或根本没有匹配,返回None)

lastindex 最后匹配的分组的整数索引(从1开始). (如果没有匹配返回 None)

re 创建 m 对象的方法所属的正则表达式对象.

string 传递给方法 match, search, sub, 或 subn 的字符串 s

一个 match 对象也支持以下方法:

1.10.1. end, span, start 方法

m.end(groupid=0)

m.span(groupid=0)

m.start(groupid=0)

这些方法返回 m.string 中的由groupid 确定的分组所匹配的子串的定界索引.这里 groupid 可以是一个分组的编号或名字. 当匹配子串是 m.string[i:j] 时, m.start 返回 i, m.end 返回 j, m.span 返回 (i, j). 当分组没有匹配时, i 和 j 的值为 -1.

1.10.2. expand 方法

m.expand(s)

返回 s 的一个拷贝, 其中转义序列和向后引用以和 r.sub 同样的方式进行了了替换. 前一小节有详述.

1.10.3. group 方法

m.group(groupid=0,*groupids)

当以一个单一的 groupid 参数(一个分组编号或名字)调用时, m.group 返回匹配该分组的子串或 None(没有匹配时). 一个惯用的方式就是 m.group( ), 也就是 m.group(0), 返回整个匹配子串(group 编号 0 暗指整个正则表达式).

当以多参数的方式调用时, 每个参数必须是一个分组编号或分组名字. 这时 m.group 就返回一个tuple(每个元素对应一个参数), 元素的是匹配相应分组的子串或 None (未发生匹配时).

1.10.4. groups 方法

m.groups(default=None)

返回一个tuple,tuple的每个元素分别是模式中的分组。如果匹配失败,则返回 none.

1.10.5. groupdict 方法

m.groupdict(default=None)

返回一个 key 为表达式 r 中的命名分组名字的一个字典. 每个名字的值是相应的匹配子串,或者在未有匹配时 default 的值.

1.11. 9.7.11 模块 re 中的函数

模块 re 不仅提供了 9.7.6 节中的属性,它还提供了与正则表达式对象的每个方法功能相同的函数。(findall, match, search, split, sub, and subn), 这些函数的第一个参数就是模式字符串。显然这些函数内部也是将这个模式字符串编译为正则表达式对象后再处理的。通常显示的将模式字符串编译为正则表达式对象然后调用该对象的方式更好些,不过,对于某些模式的一次性使用,使用函数更方便一些。举例来说,统计'hello'在一个字符串中出现的次数(不区分大小写),象下面这样做:
Toggle line numbers

___FCKpd___19

象上面这种方式使用正则表达式,正则表达式选项必须内嵌在模式字符串内(例如在这个例子里的大小写不敏感选项,即(?i)),这是因为这些函数被设计成不接受标志选项参数。

模块 re 也提供了错误处理,当发生错误时会引发异常(通常都是模式字符串的语法错误)。 re模块还提供了两个另外的函数:

1.11.1. compile 函数

compile(pattern,flags=0)

解析模式字符串中的每一个语法元素,若无错误则创建并返回一个正则表达式对象。

1.11.2. escape 函数

escape(s)

返回一个字符串s的拷贝,不过s中的所有非字母数字字符在新串中均已被转义(在其前面添加反斜杠)。
, re.MULTILINE) 3 for first, last in first_last.findall(open('afile.txt').read( )): 4 print first, last

1.9.5. match 方法

r.match(s,start=0,end=sys.maxint)

当匹配时,返回一个 match 对象,否则返回 None. 注意这个匹配严格的从字符串的 start 位置开始. 要在整个字符串中向前搜索匹配,使用 r.search 而不是 r.match. 下面的例子演示了如何打印出一个文件中所有以数字开头的行:
Toggle line numbers

___FCKpd___8

1.9.6. search 方法

r.search(s,start=0,end=sys.maxint)

如果匹配成功,返回一个匹配最左边子串的 match 对象,否则返回 None.下面的例子演示了如何打印出含有数字的行:
Toggle line numbers

___FCKpd___9

1.9.7. split 方法

r.split(s,maxsplit=0)

返回一个该匹配分隔的子串列表.举例来说,要排除一个字符串中所有的 'hello' 不区分大小写,可以这样:
Toggle line numbers

___FCKpd___10

如果 r 有多个分组,则分隔的规则就会象下面这样。下面这个例子只删除位于一个冒号(:)和数字之间的空白。
Toggle line numbers

___FCKpd___11

这个例子可以说明更多问题:

___FCKpd___12

若 maxsplit 大于 0, 则至多进行 maxsplit 次分隔,剩下的部分则成为列表的最后一个元素。下面的例子只删除第一个匹配的'hello':

___FCKpd___13

1.9.8. sub 函数

r.sub(repl,s,count=0)

返回字符串s的一个拷贝,该串中的所有匹配均被替换成了 repl 。repl可以是一个字符串或一个可调用对象(函数或别的东西)。仅当不存在前一个匹配时,使用空的匹配(空串)替换. 当 count 大于 0 时, 只有前 count 个匹配被替换。若 count 等于 0, 所有的匹配都被替换. 下面的例子提供了删除目的字符串中第一次出现的 'hello' (不区分大小写)的另外一种方式:
Toggle line numbers

___FCKpd___14

如果例子中的 sub 方法没有最后一个参数, 则例子中的字符串 astring 中的所有 'hello' 均被删除。

若 repl 是一个可调用对象, repl 必须接受且仅接受一个 match 对象做为参数,并返回用来替换匹配的字符串。 sub 调用 repl, 并提供给 repl 一个合适的 match-object 参数, repl则为每个匹配返回一个替换值。还是举个例子表述的清楚,要将所有首字母为'h',末字母为 'o' 的匹配单词转化为大写,你可以这么做:
Toggle line numbers

___FCKpd___15

在你不需要对匹配进行替换而是需要对这些匹配进行更复杂的处理时,sub 方法非常有用. 下面这个例子展示了 sub 方法的使用,它用来对一个没有分组的正则表达式生成一个类似 findall 方法的函数.
Toggle line numbers

___FCKpd___16

这个例子需要 Python 2.2 或更高, 不仅仅是因为它使用了嵌套作用域, 更大的原因是 Python 2.2 允许 repl 返回None并且视为其返回一个空串(). 而 Python 2.1则太轴,在Python2.1中,只允许 repl 返回一个字符串.

若 repl 是一个字符串而且它不是一个向后引用时, sub 使用 repl 自身作为替换.向后引用是一个 \g 形式的 repl 子串,这里 id 是 r 中一个分组的名字(由 r 中模式字符串中的 (?P) 建立), 或 \dd, 这里 dd 是一个或两个数字,代表一个分组的编号. 每个向后引用,不论是命名的还是编号的, 都被其所代码的匹配内容所替换.举例来说,下面这个将每个单词放入大括号中:
Toggle line numbers

___FCKpd___17

1.9.9. subn 函数

r.subn(repl,s,count=0)

subn 与 sub 相同, 只是 subn 返回一个元组 (new_string, n) ,这里 n 是 subn 替换的数字.看这个例子, 要统计子串'hello'出现的次数,一个方法是:
Toggle line numbers

___FCKpd___18

1.10. 9.7.10 Match 对象

正则表达式对象的 match 和 search 方法创建并返回 Match 对象. 当 repl 参数为可调用对象时, sub 及 subn 方法也会在幕后悄悄生成 Match 对象并使用.(在那种情况下一个相应的 match 对象被作为实参传递给 repl 对象.一个match 对象 m 支持以下属性:

pos 起始位置. 传递给 match 或 search 对象的开始位置参数(也就是字符串s开始匹配位置)

endpos 结束位置.传递给 match 或 search 对象的结束位置参数(也就是字符串s结束匹配位置)

lastgroup 最后匹配的分组的名字(或分组没有名字或根本没有匹配,返回None)

lastindex 最后匹配的分组的整数索引(从1开始). (如果没有匹配返回 None)

re 创建 m 对象的方法所属的正则表达式对象.

string 传递给方法 match, search, sub, 或 subn 的字符串 s

一个 match 对象也支持以下方法:

1.10.1. end, span, start 方法

m.end(groupid=0)

m.span(groupid=0)

m.start(groupid=0)

这些方法返回 m.string 中的由groupid 确定的分组所匹配的子串的定界索引.这里 groupid 可以是一个分组的编号或名字. 当匹配子串是 m.string[i:j] 时, m.start 返回 i, m.end 返回 j, m.span 返回 (i, j). 当分组没有匹配时, i 和 j 的值为 -1.

1.10.2. expand 方法

m.expand(s)

返回 s 的一个拷贝, 其中转义序列和向后引用以和 r.sub 同样的方式进行了了替换. 前一小节有详述.

1.10.3. group 方法

m.group(groupid=0,*groupids)

当以一个单一的 groupid 参数(一个分组编号或名字)调用时, m.group 返回匹配该分组的子串或 None(没有匹配时). 一个惯用的方式就是 m.group( ), 也就是 m.group(0), 返回整个匹配子串(group 编号 0 暗指整个正则表达式).

当以多参数的方式调用时, 每个参数必须是一个分组编号或分组名字. 这时 m.group 就返回一个tuple(每个元素对应一个参数), 元素的是匹配相应分组的子串或 None (未发生匹配时).

1.10.4. groups 方法

m.groups(default=None)

返回一个tuple,tuple的每个元素分别是模式中的分组。如果匹配失败,则返回 none.

1.10.5. groupdict 方法

m.groupdict(default=None)

返回一个 key 为表达式 r 中的命名分组名字的一个字典. 每个名字的值是相应的匹配子串,或者在未有匹配时 default 的值.

1.11. 9.7.11 模块 re 中的函数

模块 re 不仅提供了 9.7.6 节中的属性,它还提供了与正则表达式对象的每个方法功能相同的函数。(findall, match, search, split, sub, and subn), 这些函数的第一个参数就是模式字符串。显然这些函数内部也是将这个模式字符串编译为正则表达式对象后再处理的。通常显示的将模式字符串编译为正则表达式对象然后调用该对象的方式更好些,不过,对于某些模式的一次性使用,使用函数更方便一些。举例来说,统计'hello'在一个字符串中出现的次数(不区分大小写),象下面这样做:
Toggle line numbers

___FCKpd___19

象上面这种方式使用正则表达式,正则表达式选项必须内嵌在模式字符串内(例如在这个例子里的大小写不敏感选项,即(?i)),这是因为这些函数被设计成不接受标志选项参数。

模块 re 也提供了错误处理,当发生错误时会引发异常(通常都是模式字符串的语法错误)。 re模块还提供了两个另外的函数:

1.11.1. compile 函数

compile(pattern,flags=0)

解析模式字符串中的每一个语法元素,若无错误则创建并返回一个正则表达式对象。

1.11.2. escape 函数

escape(s)

返回一个字符串s的拷贝,不过s中的所有非字母数字字符在新串中均已被转义(在其前面添加反斜杠)。
, re.MULTILINE) 3 if re.search(open('afile.txt').read()): print "some lines end with digits" 4 else: print "no lines end with digits"

模式 r'\d\n' 几乎与r'\d$'同义, 但是当一个文件以数字却没有回车结尾时,匹配将会失败。

1.9. 9.7.9 正则表达式对象

正则表达式对象 r 拥有下列只读属性, 这些属性详细描述了 r 是被如何创建出来的。 (通过模块 re 中的 compile 函数,见后文):

1.9.1. flags

传递给 compile 函数的 flags 参数, 如果省略了 flags 参数则为 0

1.9.2. groupindex

一个字典,它的 key 是通过元素(?P)定义的组的名字; 相应的值则是该组的序号。

1.9.3. pattern

编译 r 使用的模式字符串

这些属性让你很容易的重新得到该对象被编译时使用的模式字符串和参数,再也不需要将它们保存到一个单独地方了了。

正则表达式对象 r 同样提供了很多方法来定位一个字符串中的正则表达式的匹配, 以便进行替换或其它操作,匹配通常由特殊对象表示, 9.7.10节会详细介绍.

1.9.4. findall 方法

r.findall(s)

当 r 没有分组时, findall 返回一个字符串列表, 每个字符串都是 s 中不重叠的 r 的匹配. 下面的例子演示了如何打印出一个文件中的所有单词:
Toggle line numbers

___FCKpd___5

当 r 有一个分组时, findall 也返回一个字符串列表,列表中的每个字符串都是这个分组的匹配. 举例来说,如果你希望打印出所有的单词(不包括标点),你只需要在上面的例子里修改一个语句:

___FCKpd___6

当 r 有 n 个分组时 ( n > 1), findall 返回一个tuple的列表, 包括每一个不重叠的匹配. 每个tuple 有 n 个元素, 每个元素对应一个分组. 下面的例子打印出每行的第一个和最后一个单词(当然是匹配至少有两个单词的行).
Toggle line numbers

___FCKpd___7

1.9.5. match 方法

r.match(s,start=0,end=sys.maxint)

当匹配时,返回一个 match 对象,否则返回 None. 注意这个匹配严格的从字符串的 start 位置开始. 要在整个字符串中向前搜索匹配,使用 r.search 而不是 r.match. 下面的例子演示了如何打印出一个文件中所有以数字开头的行:
Toggle line numbers

___FCKpd___8

1.9.6. search 方法

r.search(s,start=0,end=sys.maxint)

如果匹配成功,返回一个匹配最左边子串的 match 对象,否则返回 None.下面的例子演示了如何打印出含有数字的行:
Toggle line numbers

___FCKpd___9

1.9.7. split 方法

r.split(s,maxsplit=0)

返回一个该匹配分隔的子串列表.举例来说,要排除一个字符串中所有的 'hello' 不区分大小写,可以这样:
Toggle line numbers

___FCKpd___10

如果 r 有多个分组,则分隔的规则就会象下面这样。下面这个例子只删除位于一个冒号(:)和数字之间的空白。
Toggle line numbers

___FCKpd___11

这个例子可以说明更多问题:

___FCKpd___12

若 maxsplit 大于 0, 则至多进行 maxsplit 次分隔,剩下的部分则成为列表的最后一个元素。下面的例子只删除第一个匹配的'hello':

___FCKpd___13

1.9.8. sub 函数

r.sub(repl,s,count=0)

返回字符串s的一个拷贝,该串中的所有匹配均被替换成了 repl 。repl可以是一个字符串或一个可调用对象(函数或别的东西)。仅当不存在前一个匹配时,使用空的匹配(空串)替换. 当 count 大于 0 时, 只有前 count 个匹配被替换。若 count 等于 0, 所有的匹配都被替换. 下面的例子提供了删除目的字符串中第一次出现的 'hello' (不区分大小写)的另外一种方式:
Toggle line numbers

___FCKpd___14

如果例子中的 sub 方法没有最后一个参数, 则例子中的字符串 astring 中的所有 'hello' 均被删除。

若 repl 是一个可调用对象, repl 必须接受且仅接受一个 match 对象做为参数,并返回用来替换匹配的字符串。 sub 调用 repl, 并提供给 repl 一个合适的 match-object 参数, repl则为每个匹配返回一个替换值。还是举个例子表述的清楚,要将所有首字母为'h',末字母为 'o' 的匹配单词转化为大写,你可以这么做:
Toggle line numbers

___FCKpd___15

在你不需要对匹配进行替换而是需要对这些匹配进行更复杂的处理时,sub 方法非常有用. 下面这个例子展示了 sub 方法的使用,它用来对一个没有分组的正则表达式生成一个类似 findall 方法的函数.
Toggle line numbers

___FCKpd___16

这个例子需要 Python 2.2 或更高, 不仅仅是因为它使用了嵌套作用域, 更大的原因是 Python 2.2 允许 repl 返回None并且视为其返回一个空串(). 而 Python 2.1则太轴,在Python2.1中,只允许 repl 返回一个字符串.

若 repl 是一个字符串而且它不是一个向后引用时, sub 使用 repl 自身作为替换.向后引用是一个 \g 形式的 repl 子串,这里 id 是 r 中一个分组的名字(由 r 中模式字符串中的 (?P) 建立), 或 \dd, 这里 dd 是一个或两个数字,代表一个分组的编号. 每个向后引用,不论是命名的还是编号的, 都被其所代码的匹配内容所替换.举例来说,下面这个将每个单词放入大括号中:
Toggle line numbers

___FCKpd___17

1.9.9. subn 函数

r.subn(repl,s,count=0)

subn 与 sub 相同, 只是 subn 返回一个元组 (new_string, n) ,这里 n 是 subn 替换的数字.看这个例子, 要统计子串'hello'出现的次数,一个方法是:
Toggle line numbers

___FCKpd___18

1.10. 9.7.10 Match 对象

正则表达式对象的 match 和 search 方法创建并返回 Match 对象. 当 repl 参数为可调用对象时, sub 及 subn 方法也会在幕后悄悄生成 Match 对象并使用.(在那种情况下一个相应的 match 对象被作为实参传递给 repl 对象.一个match 对象 m 支持以下属性:

pos 起始位置. 传递给 match 或 search 对象的开始位置参数(也就是字符串s开始匹配位置)

endpos 结束位置.传递给 match 或 search 对象的结束位置参数(也就是字符串s结束匹配位置)

lastgroup 最后匹配的分组的名字(或分组没有名字或根本没有匹配,返回None)

lastindex 最后匹配的分组的整数索引(从1开始). (如果没有匹配返回 None)

re 创建 m 对象的方法所属的正则表达式对象.

string 传递给方法 match, search, sub, 或 subn 的字符串 s

一个 match 对象也支持以下方法:

1.10.1. end, span, start 方法

m.end(groupid=0)

m.span(groupid=0)

m.start(groupid=0)

这些方法返回 m.string 中的由groupid 确定的分组所匹配的子串的定界索引.这里 groupid 可以是一个分组的编号或名字. 当匹配子串是 m.string[i:j] 时, m.start 返回 i, m.end 返回 j, m.span 返回 (i, j). 当分组没有匹配时, i 和 j 的值为 -1.

1.10.2. expand 方法

m.expand(s)

返回 s 的一个拷贝, 其中转义序列和向后引用以和 r.sub 同样的方式进行了了替换. 前一小节有详述.

1.10.3. group 方法

m.group(groupid=0,*groupids)

当以一个单一的 groupid 参数(一个分组编号或名字)调用时, m.group 返回匹配该分组的子串或 None(没有匹配时). 一个惯用的方式就是 m.group( ), 也就是 m.group(0), 返回整个匹配子串(group 编号 0 暗指整个正则表达式).

当以多参数的方式调用时, 每个参数必须是一个分组编号或分组名字. 这时 m.group 就返回一个tuple(每个元素对应一个参数), 元素的是匹配相应分组的子串或 None (未发生匹配时).

1.10.4. groups 方法

m.groups(default=None)

返回一个tuple,tuple的每个元素分别是模式中的分组。如果匹配失败,则返回 none.

1.10.5. groupdict 方法

m.groupdict(default=None)

返回一个 key 为表达式 r 中的命名分组名字的一个字典. 每个名字的值是相应的匹配子串,或者在未有匹配时 default 的值.

1.11. 9.7.11 模块 re 中的函数

模块 re 不仅提供了 9.7.6 节中的属性,它还提供了与正则表达式对象的每个方法功能相同的函数。(findall, match, search, split, sub, and subn), 这些函数的第一个参数就是模式字符串。显然这些函数内部也是将这个模式字符串编译为正则表达式对象后再处理的。通常显示的将模式字符串编译为正则表达式对象然后调用该对象的方式更好些,不过,对于某些模式的一次性使用,使用函数更方便一些。举例来说,统计'hello'在一个字符串中出现的次数(不区分大小写),象下面这样做:
Toggle line numbers

___FCKpd___19

象上面这种方式使用正则表达式,正则表达式选项必须内嵌在模式字符串内(例如在这个例子里的大小写不敏感选项,即(?i)),这是因为这些函数被设计成不接受标志选项参数。

模块 re 也提供了错误处理,当发生错误时会引发异常(通常都是模式字符串的语法错误)。 re模块还提供了两个另外的函数:

1.11.1. compile 函数

compile(pattern,flags=0)

解析模式字符串中的每一个语法元素,若无错误则创建并返回一个正则表达式对象。

1.11.2. escape 函数

escape(s)

返回一个字符串s的拷贝,不过s中的所有非字母数字字符在新串中均已被转义(在其前面添加反斜杠)。

python模块之----shutil模块 不指定

zeus , 2010/03/14 00:58 , Python , Comments(0) , Reads(587) , Via Original
copy(src, dst)
Copy data and mode bits ("cp src dst").

The destination may be a directory.

copy2(src, dst)
Copy data and all stat info ("cp -p src dst").

The destination may be a directory.

copyfile(src, dst)
Copy data from src to dst

copyfileobj(fsrc, fdst, length=16384)
copy data from file-like object fsrc to file-like object fdst

copymode(src, dst)
Copy mode bits from src to dst

copystat(src, dst)
Copy all stat info (mode bits, atime and mtime) from src to dst

copytree(src, dst, symlinks=False)
Recursively copy a directory tree using copy2().

The destination directory must not already exist.
If exception(s) occur, an Error is raised with a list of reasons.

If the optional symlinks flag is true, symbolic links in the
source tree result in symbolic links in the destination tree; if
it is false, the contents of the files pointed to by symbolic
links are copied.

XXX Consider this example code rather than the ultimate tool.

move(src, dst)
Recursively move a file or directory to another location.

If the destination is on our current filesystem, then simply use
rename. Otherwise, copy src to the dst and then remove src.
A lot more could be done here... A look at a mv.c shows a lot of
the issues this implementation glosses over.

rmtree(path, ignore_errors=False, onerror=None)
Recursively delete a directory tree.

If ignore_errors is set, errors are ignored; otherwise, if onerror
is set, it is called to handle the error with arguments (func,
path, exc_info) where func is os.listdir, os.remove, or os.rmdir;
path is the argument to that function that caused it to fail; and
exc_info is a tuple returned by sys.exc_info(). If ignore_errors
is false and onerror is None, an exception is raised.
简介:
urllib2是python的一个获取url(Uniform Resource Locators,统一资源定址器)的模块。它用urlopen函数的形式提供了一个非常简洁的接口。这使得用各种各样的协议获取url成为可能。它同时 也提供了一个稍微复杂的接口来处理常见的状况-如基本的认证,cookies,代理,等等。这些都是由叫做opener和handler的对象来处理的。

以下是获取url最简单的方式:

import urllib2
response = urllib2.urlopen('http://python.org/')
html = response.read()

许多urlib2的使用都是如此简单(注意我们本来也可以用一个以”ftp:”"file:”等开头的url取代”HTTP”开头的url).然而,这篇教程的目的是解释关于HTTP更复杂的情形。HTTP建基于请求和回应(requests &responses )-客户端制造请求服务器返回回应。urlib2用代 表了你正在请求的HTTP request的Request对象反映了这些。用它最简单的形式,你建立了一个Request对象来明确指明你想要获取的url。调用urlopen函 数对请求的url返回一个respons对象。这个respons是一个像file的对象,这意味着你能用.read()函数操作这个respon对象:

import urllib2

req = urllib2.Request('http://www.voidspace.org.uk')
response = urllib2.urlopen(req)
the_page = response.read()

注意urlib2利用了同样的Request接口来处理所有的url协议。例如,你可以像这样请求一个ftpRequest:

req = urllib2.Request('ftp://example.com/')

对于HTTP,Request对象允许你做两件额外的事:第一,你可以向服务器发送数据。第二,你可以向服务器发送额外的信息(metadata),这些信息可以是关于数据本身的,或者是关于这个请求本身的–这些信息被当作HTTP头发送。让我们依次看一下这些。

数据:
有时你想向一个URL发送数据(通常这些数据是代表一些CGI脚本或者其他的web应用)。对于HTTP,这通常叫做一个Post。当你发送一个你 在网上填的form(表单)时,这通常是你的浏览器所做的。并不是所有的Post请求都来自HTML表单,这些数据需要被以标准的方式encode,然后 作为一个数据参数传送给Request对象。Encoding是在urlib中完成的,而不是在urlib2中完成的。

import urllib
import urllib2

url = 'http://www.someserver.com/cgi-bin/register.cgi'
values = {'name' : 'Michael Foord',
'location' : 'Northampton',
'language' : 'Python' }

data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
the_page = response.read()

如果你不传送数据参数,urlib2使用了一个GET请求。一个GET请求和POST请求的不同之处在于POST请求通常具有边界效应:它们以某种 方式改变系统的状态。(例如,通过网页设置一条指令运送一英担罐装牛肉到你家。)虽然HTTP标准清楚的说明Post经常产生边界效应,而get从不产生 边界效应,但没有什么能阻止一个get请求产生边界效应,或一个Post请求没有任何边界效应。数据也能被url自己加密(Encoding)然后通过一 个get请求发送出去。

这通过以下实现:
>>> import urllib2
>>> import urllib
>>> data = {}
>>> data['name'] = 'Somebody Here'
>>> data['location'] = 'Northampton'
>>> data['language'] = 'Python'
>>> url_values = urllib.urlencode(data)
>>> print url_values
name=Somebody+Here&language=Python&location=Northampton
>>> url = 'http://www.example.com/example.cgi'
>>> full_url = url + '?' + url_values
>>> data = urllib2.open(full_url)

头:
我们将会在这里讨论一个特殊的HTTP头,来阐释怎么向你的HTTP请求中加入头。
有一些网站不希望被某些程序浏览或者针对不同的浏览器返回不同的版本。默认情况下,urlib2把自己识别为Python-urllib/x.y(这里的xy是python发行版的主要或次要的版本号,如, Python-urllib/2.5),这些也许会混淆站点,或者完全不工作。浏览器区别自身的方式是通过User-Agent头。当你建立一个Request对象时,你可以加入一个头字典。接下来的这个例子和上面的请求一样,不过它把自己定义为IE的一个版本。

import urllib
import urllib2

url = 'http://www.someserver.com/cgi-bin/register.cgi'
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
values = {'name' : 'Michael Foord',
'location' : 'Northampton',
'language' : 'Python' }
headers = { 'User-Agent' : user_agent }

data = urllib.urlencode(values)
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)
the_page = response.read()

Respons同样有两种有用的方法。当我们出差错之后,看一下关于info and geturl的部分。

异常处理:

不能处理一个respons时,urlopen抛出一个urlerror(虽然像平常一样对于python APIs,内建异常如,ValueError, TypeError 等也会被抛出。)
HTTPerror是HTTP URL在特别的情况下被抛出的URLError的一个子类。
urlerror:
通常,urlerror被抛出是因为没有网络连接(没有至特定服务器的连接)或者特定的服务器不存在。在这种情况下,含有reason属性的异常将被抛出,以一种包含错误代码和文本错误信息的tuple形式。

e.g.
>>> req = urllib2.Request('http://www.pretend_server.org')
>>> try: urllib2.urlopen(req)
>>> except URLError, e:
>>> print e.reason
>>>
(4, 'getaddrinfo failed')

当一个错误被抛出的时候,服务器返回一个HTTP错误代码和一个错误页。你可以使用返回的HTTP错误示例。这意味着它不但具有code属性,而且同时具有read,geturl,和info,methods属性。>>> req = urllib2.Request('http://www.python.org/fish.html')>>> try:>>> urllib2.urlopen(req)>>> except URLError, e:>>> print e.code>>> print e.read()>>>404...... etc

容错:
如果你准备处理HTTP错误和URL错误这里有两种基本的方法,我更倾向于后一种:

1.
from urllib2 import Request, urlopen, URLError, HTTPError
req = Request(someurl)
try:
response = urlopen(req)
except HTTPError, e:
print 'The server couldn\'t fulfill the request.'
print 'Error code: ', e.code
except URLError, e:
print 'We failed to reach a server.'
print 'Reason: ', e.reason
else:
# everything is fine

注意:HTTP错误异常必须在前面,否则URL错误也会捕获一个HTTP错误。
2
from urllib2 import Request, urlopen, URLError
req = Request(someurl)
try:
response = urlopen(req)
except URLError, e:
if hasattr(e, 'reason'):
print 'We failed to reach a server.'
print 'Reason: ', e.reason
elif hasattr(e, 'code'):
print 'The server couldn\'t fulfill the request.'
print 'Error code: ', e.code
else:
# everything is fine

注意:URL错误是IO错误异常的一个子类。这意味着你能避免引入(import)URL错误而使用:

from urllib2 import Request, urlopen
req = Request(someurl)
try:
response = urlopen(req)
except IOError, e:
if hasattr(e, 'reason'):
print 'We failed to reach a server.'
print 'Reason: ', e.reason
elif hasattr(e, 'code'):
print 'The server couldn\'t fulfill the request.'
print 'Error code: ', e.code
else:
# everything is fine

极少数环境下,urllib2能够抛出socket.error.

INFO and GETURL
urlopen返回的response(或者HTTP错误实例)有两个有用的方法:info和geturl。

geturl–它返回被获取网页的真正的url。这是很有用的,因为urlopen(或使用的opener对象)也许会伴随一个重定向。
获取的网页url也许和要求的网页url不一样。

info–它返回一个像字典的对象来描述获取的网页,尤其是服务器发送的头。它现在一般是httplib.HTTPMessage的一个实例。
典型的头包含'Content-length', 'Content-type', 等等。看一下Quick Reference to HTTP Headers中,HTTP头列表,还有
关于他们简单的解释和使用方法。
Openers 和Handlers
当你获取一个URL时,你使用一个opener(一个可能以一个比较迷糊名字命名的实例–urllib2.OpenerDirector)。正常情况下
我们一直使用默认的opener,通过urlopen,但你也可以创建自定义的openers。opener使用操作器(handlers)。所有的重活都交给这些handlers来做。每一个handler知道
怎么打开url以一种独特的url协议(http,ftp等等),或者怎么处理打开url的某些方面,如,HTTP重定向,或者HTTP cookie。

你将会创建openers如果你想要用安装特别的handlers获取url,例如,获取一个处理cookie的opener,或者一个不处理重定向的opener。

枚举一个OpenerDirector,然后多次调用.add_handler(some_handler_instance)来创建一个opener。
或者,你可以用build_opener,这是一个很方便的创建opener对象的函数,它只有一个函数调用。build_opener默认会加入许多
handlers,但是提供了一个快速的方法添加更多东西和/或使默认的handler失效。
其他你想要的handlers能够处理代理,authentication和其他平常但是又有些特殊的情况。
install_opener能被用于创建一个opener对象,(全局)默认的opener。这意味着调用urlopen将会用到你刚安装的opener。
opener对象有一个open方法,它可以被直接调用来获取url以一种和urlopen函数同样的方式:没有必要调用install_opener,除非是为了方便。

Basic Authentication:(基本验证)

为了解释创建和安装一个handler,我们将会使用 HTTPBasicAuthHandler。更多关于这个东西的内容和详细讨论—包括一个 Basic Authentication如何工作的解说–参见 Basic Authentication Tutorial.

当需要Authentication的时候,服务器发送一个头(同时还有401代码)请求Authentication。它详细指明了一个Authentication和一个域。这个头看起来像:

Www-authenticate: SCHEME realm=”REALM”.
e.g.
Www-authenticate: Basic realm=”cPanel Users”

客户端然后就会用包含在头中的正确的帐户和密码重新请求这个域。这是”基本验证”。为了简化这个过程,我们可以创建一个
HTTPBasicAuthHandler和opener的实例来使用这个handler。
HTTPBasicAuthHandler用一个叫做密码管理的对象来处理url和用户名和密码的域的映射。如果你知道域是什么(从服务器发送的authentication
头中),那你就可以使用一个HTTPPasswordMgr。多数情况下人们不在乎域是什么。那样使用HTTPPasswordMgrWithDefaultRealm就很方便。它
允许你为一个url具体指定用户名和密码。这将会在你没有为一个特殊的域提供一个可供选择的密码锁时提供给你。我们通过提供None作为add_password方法域的参数指出
这一点。
最高级别的url是需要authentication的第一个url。比你传递给.add_password()的url更深的url同样也会匹配。

# create a password manager
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
# Add the username and password.
# If we knew the realm, we could use it instead of “None“.
top_level_url = “http://example.com/foo/”
password_mgr.add_password(None, top_level_url, username, password)

handler = urllib2.HTTPBasicAuthHandler(password_mgr)
# create “opener” (OpenerDirector instance)
opener = urllib2.build_opener(handler)
# use the opener to fetch a URL
opener.open(a_url)
# Install the opener.
# Now all calls to urllib2.urlopen use our opener.
urllib2.install_opener(opener)

注意:在以上的示例中我们只给build_opener提供了HTTPBasicAuthHandler。默认opener有对普通情况的操作器 (handlers)- ProxyHandler, UnknownHandler, HTTPHandler, HTTPDefaultErrorHandler, HTTPRedirectHandler, FTPHandler, FileHandler, HTTPErrorProcessor.
高级别url实际上是一个完整的url(包括http:协议组件和主机名可选的端口号),如”http://example.com”或者是一个授权(同样,主机名,可选的端口号)
如”"example.com” 或 “example.com:8080″(后一个示例包含了一个端口号)。授权,如果被呈现,一定不能包含用户信息-如”oe@password:example.com”
是不正确的、
代理:
urllib2将会自动检测你的代理设置并使用它们。这是通过 ProxyHandler实现的,它是操作器链的一部分。正常情况下,这是个好东西,但是也有它不那么有用的偶然情况。
一个做这些的方法是安装我们自己的ProxyHandler,不用任何定义任何代理。使用一个和建立Basic Authentication操作器相似的步骤可以实现:

>>> proxy_support = urllib2.ProxyHandler({})
>>> opener = urllib2.build_opener(proxy_support)
>>> urllib2.install_opener(opener)
注意:
目前urllib2不支持通过代理获取HTTPs位置。这是一个问题。
sockets和layers
python支持获取层叠的网页的源码。urllib2使用httplib library,而httplib library反过来使用socket library。
对于python2.3你可以指明一个socket应该在超时之前等待response多久。这在这些不得不获取网页的应用中很有用。默认socket模块没有超时而且能够挂起。
目前,socket超时在urllib2或者httplib水平中不可见。然而,你可以全局地为所有socket设置默认的超时。

import socket
import urllib2
# timeout in seconds
timeout = 10
socket.setdefaulttimeout(timeout)
# this call to urllib2.urlopen now uses the default timeout
# we have set in the socket module
req = urllib2.Request('http://www.voidspace.org.uk')
response = urllib2.urlopen(req)

Open in new window
奥库兹的冒险者是一款类似暗黑的超级热门的ARPG游戏,作为一款FLASH游戏,大小只有约14M,但游戏界面华丽,特别是必弑技非常绚,游戏操作简单,可玩性也很强,都能够做得如此难能可贵。
游戏构建了一个相对完整的故事舞台,一切都围绕着被冠予奥库慈村希望的勇者青年而展开。精致的游戏画面,丰富的装备道具,完善的升级与任务系统,流畅的操作手感和漂亮的攻击招式,让它成为了款不逊色于单机游戏素质的优秀作品。

虽然上面的介绍可能显得过于官方,但是游戏也确实配得上这些称赞。其实还有一点原因就是这款游戏实际上是由一个国人团队(funnaut)开发的。游戏十分牛逼的内置了包括中文在内的六国语言,消除了语言上的隔阂。

游戏风格是颇受东方玩家喜爱的日系RPG,如果玩过伊苏系列的玩家可能对游戏的上手会很快,因为游戏是在斜45度视角下的场景中,在空中以及地面进行的即时战斗操作。不过游戏并没有模仿伊苏饱受诟病的打击感,奥库兹在打击感方面进行了不错的改良。游戏中玩家的职业虽然都是“勇者”,但是不同的勇者能使用不同的武器,斧头攻击高但是速度慢,弯刀速度快但是攻击偏低,而剑则是性能均衡的武器,想怎样游戏全看你的喜好。此外技能树也让人眼前一亮,主动技与被动技让游戏的趣味性大增,不过想要学会全部的技能不太容易,那么只好选择做一名魔战士或者狂战士了,而且选择自己喜欢的路线专一修炼还可以让你更加轻松的游戏。装备的锻造系统则是最受喜欢的部分了。想必很多玩家在玩ARPG的时候都有收集或者打造属于自己的极品武器的爱好吧,奥库兹应该就能满足你。利用风地水火四个基本元素你能组合出10种不同的属性攻击,在野外通过杀怪你也可以获得属性异于普通武器的极品兵器,打造一把好武器绝对可以让你在杀敌之时大呼过瘾。

Flash Player File
Tags:

windows python mysqlDB 数据库连接 不指定

zeus , 2010/03/13 19:07 , Python , Comments(0) , Reads(507) , Via Original
1.安装数据库支持包,
由于windows下mysqldb的ports已经有2.6的,所有大家可以放心用2.6就可以了。
http://sourceforge.net/projects/mysql-python/forums/forum/70460/topic/3108914
上面的链接有讨论,找到自己喜欢的版本下载就可以了。我用的这个
MySQL-python-1.2.3c1.win32-py2.6.exe

2,然后就是使用包了 非常简单。
值得注意的是多用UTF8这个编码,会让你少走很多冤枉路。

import MySQLdb把模块加载进来了。并连上了数据库
老版本链接不能指定编码如下

(conn=MySQLdb.connect(host='localhost',user='root',passwd='1234556',db='test')

新的可以了

Connection(host='localhost',port=3306,user='root',passwd='123456',db='test',charset='utf8')


例子程序 不是我写的,拿来用吧。
总结MySQLdb的操作

#!/usr/bin/python
# -*- coding: gbk -*-
import MySQLdb
conn=MySQLdb.connect(host="localhost",user="root",passwd="123456",db="test")
cursor = conn.cursor()
#更新
sql = "update users set name=%s where id=1"
param = ("完全")
cursor.execute(sql,param)
cursor.close()
#写入
sql = "insert into users(name) values(%s)"
param = ("写入")
cursor.execute(sql,param)
cursor.close()
#删除
sql = "delete from users where id=1"
cursor.execute(sql)
sql = "delete from users where name=%s"
param =("写入")
cursor.execute(sql,param)
cursor.close()
conn.close()

小白文章 高手莫来。

1. 概述

“工欲善其事,必先利其器”,如果说编程是程序员的手艺,那么IDE就是程序员的吃饭家伙了。

IDE的全称是Integration Development Environment(集成开发环境),一般以代码编辑器为核心,包括一系列周边组件和附属功能。一个优秀的IDE,最重要的就是在普通文本编辑之外,提供针对特定语言的各种快捷编辑功能,让程序员尽可能快捷、舒适、清晰的浏览、输入、修改代码。对于一个现代的IDE来说,语法着色、错误提示、代码折叠、代码完成、代码块定位、重构,与调试器、版本控制系统(VCS)的集成等等都是重要的功能。以插件、扩展系统为代表的可定制框架,是现代IDE的另一个流行趋势。

IDE并非功能越多越好,因为更多的功能往往意味着更大的复杂度,这不但会分散程序员本来的精力,而且还可能带来更多的错误。只要基本功能满足需要,符合自己使用习惯的IDE才是最好的IDE。程序员的逻辑永远是:用最合适的工具做最合适的事情。

正因为此,比起大而全的IDE,以单纯的文本编辑器结合独立的调试器、交互式命令行等外部小工具也是另一种开发方式。由于python本身的简洁,因此在写小的代码片段以及通过示例代码学习时这种方式尤其适合。

2. 常用IDE简介

这里简单介绍Python程序员中最流行的若干IDE。

2.1. 内置IDE

Python的各个常见发行版都有内置的IDE,虽然它们的功能一般不够强大完整,但简便易得就是最大的优势。 对于初学者来说,它们也是上手的最好选择,可以让你更专注于语言本身而不会被繁复的IDE分散精力。

2.1.1. IDLE

IDLE是Python标准发行版内置的一个简单小巧的IDE,包括了交互式命令行、编辑器、调试器等基本组件,足以应付大多数简单应用。 IDLE是用纯Python基于Tkinter编写的的,最初的作者正是Python之父Guido van Rossum本人。

http://hkn.eecs.berkeley.edu/~dyoo/python/idle_intro/index.html -- 《One Day of IDLE Toying》,图文并茂的入门文章

http://hkn.eecs.berkeley.edu/~dyoo/python/idle_intro/IDLE-chinese.htm -- 《One Day of IDLE Toying》中文版

2.1.2. PythonWin

PythonWin是Python Win32 Extensions(半官方性质的python for win32增强包)的一部分,也包含在ActivePython的windows发行版中。如其名字所言,只针对win32平台。

总体来说,PythonWin是一个增强版的IDLE,尤其是易用性方面(就像windows本身的风格一样)。除了易用性和稳定性之外,(简单的)代码完成和更强的调试器都是相对于IDLE的明显优势。

Python Win32 Extensions的下载页:http://sourceforge.net/projects/pywin32/

ActivePython的主页:http://www.activestate.com/Products/ActivePython/

2.1.3. MacPython IDE

MacPythonIDE是Python的Mac OS发行版内置的IDE,可以看作是PythonWin的Mac对应版本,由Guido的哥哥Just van Rossum编写。

2.2. Emacs和Vim

Emacs和Vim号称是这个星球上最强大(以及第二强大)的文本编辑器,对于许多程序员来说是万能IDE的不二(三?)选择。 比起同类的通用文本编辑器如UltraEdit,Emacs和Vim由于扩展功能的强大,可以针对性地搭建出更为完整便利的IDE。

   *

     Emacs -- Emacs及python-mode的简介
   *

     Vim -- Vim 通用编辑环境使用技巧推介
   *

     PyIDEguider、VimPython、VimPythonTDD -- 社区内几篇介绍在Vim环境下进行Python开发的文章

虽然二者掌握之后可以说是终身受益,但学习曲线都比较陡峭。由于历史原因,它们的设计理念都是基于纯ascii字符环境,GUI相对来说不是支持的重点,大量使用快捷键才能带来最大的便利。对于初学者来说,相对而言Vim更简洁一些,但Emacs的GUI与一般编辑器的习惯更接近些。

2.3. Eclipse + PyDev

Eclipse是新一代的优秀泛用型IDE,虽然是基于Java技术开发的,但出色的架构使其具有不逊于Emacs和Vim的可扩展性,现在已经成为了许多程序员最爱的瑞士军刀。

   *

     Eclipse -- Eclipse集成开发环境使用说明,简略介绍了Eclipse插件开发的基础知识

PyDev是Eclipse上的Python开发插件中最成熟完善的一个,而且还在持续的活跃开发中。除了 Eclipse平台提供的基本功能之外,PyDev的代码完成、语法查错、调试器、重构等功能都相当出色,可以说在开源产品中是最为强大的一个,许多贴心的小功能也很符合编辑习惯,用起来相当顺手。

速度和资源占用是致命伤,在低配置机器上跑起来比较吃力。

   *

     PyDev -- PyDev开发环境简介

Eclipse的主页:http://www.eclipse.org/

PyDev的主页:http://pydev.sourceforge.net/

PyDev使用手册:http://www.fabioz.com/pydev/manual_101_root.html (Eng) 此入门手册从安装到开发过程中的使用,并且是图文显示,推荐大家使用.

技术开发参考: 用 Eclipse,PyDev 和 Ant 进行 Python 开发,http://www-128.ibm.com/developerworks/cn/opensource/os-ecant/index.html

2.4. UliPad

UliPad是国内知名pythoner,也是PythonCN社区核心成员limodou开发的IDE。

2.5. SPE (Stani's Python Editor)

很有特色的一个轻量级python IDE,功能很全面而不失小巧轻便,特别适合写小的脚本。

即时生成代码的UML类图是独此一家的功能,此外还特别注重与外部工具的集成。例如,集成了wxGlade作为所见即所得的GUI开发环境,集成了Winpdb作为调试器,甚至还能与3D建模工具Blender集成。

SPE没有管理Project的概念,这样开发多文件多目录组成的项目时会不太方便。此外界面设计相对来说不够细致,也算是瑕疵。

SPE的主页:http://stani.be/python/spe/

2.6. Boa Constructor

专为快速开发基于wxPython的GUI程序而设计的IDE,支持“所见即所得”的控件拖放式开发,被称为Python世界中的Delphi。

曾被sourceforge推选为"Project of the Month",不过最近开发速度趋于缓慢。

Boa Constructor的主页:http://boa-constructor.sourceforge.net/

2.7. Eric3

Eric3的主页:http://www.die-offenbachs.de/detlev/eric3.html

2.8. WingIDE

Wingware公司开发的商业产品,总体来说是目前最为强大专业的Python IDE,开源项目可以申请到免费的license。

最大的缺点和PyDev一样,速度较慢,资源占用多。

Wingware的主页:http://wingware.com/

2.9. Komodo

另一个优秀的商业产品,由ActiveState公司开发,是一个泛用的脚本语言IDE,除了Python外还支持javascript、perl、php、ruby、tcl等多种语言。

Komodo的主页:http://www.activestate.com/Products/Komodo/

2.10. Textmate

Textmate是Mac OSX平台的Cocoa原生程序,类似UltraEdit。以灵活的Bundles和Code Snippets著称,支持大多数的脚本语言。Rails的全体开发团队都用这个Editor。类似Emacs/vi,需要配合ctags分析 python代码结构,可以很容易的做unittest等功能。需要特别指出的是它对于Django的model和template、以及Zope都有专门的支持。

Textmate的主页:http://macromates.com/

2.11. 综合比较

swordsp的个人建议:

   *

     初学者首选IDLE / PythonWin / MacPython
   *

     Emacs / Vim / Eclipse+PyDev是强大且通用的解决方案,取决于你更熟悉哪个环境,如果都没有基础,更推荐Eclipse+PyDev。
   * SPE是纯Python实现的简洁型IDE中功能最完善的,写小脚本的时候很方便。
   *

     Boa长处在基于wxPython的快速GUI开发。
   * 如果有条件选择商业工具,WingIDE或者Komodo都是优秀的产品。

其它比较Python IDE的文章:

http://www-128.ibm.com/developerworks/cn/linux/sdk/python/charm-14/index.html

"Charming Python"专栏作者David Mertz的测评文章,写于2001年,许多内容已经过于陈旧了,但仍有参考价值。

http://spyced.blogspot.com/2005/09/review-of-6-python-ides.html -- review-of-6-python-ides.html

http://spyced.blogspot.com/2006/02/pycon-python-ide-review.html -- pycon-python-ide-review.html

较新的两篇Python IDE测评文章(原地址需代理才能访问,后一个附件链接是本地的备份),分别比较了PyDev、Eric3、Boa Constructor、BlackAdder、Komodo、WingIDE、SPE。

3. IDE之外的工具

3.1. 交互式命令行(interactive console)

3.1.1. IPython

IPython的主页:http://ipython.scipy.org/

3.2. 调试工具(Debugger)

3.2.1. Winpdb

Winpdb的主页:http://www.digitalpeers.com/pythondebugger/

3.3. 其它支持 Python 的编辑器

3.3.1. Leo

基于全新的Literate Programming(文学化编程)理念的开发工具,详细的介绍参见:LeoEnvironment

Leo的主页:http://webpages.charter.net/edreamleo/front.html

3.3.2. Bluefish

Bluefish 通常被认为是一个类似 Homesite 的网页编辑器,但事实上它不仅如此。它应该是一个通用的文本编辑器,支持 C、PHP、Python、Ruby、Perl、Java、Shell、Tcl 等许多种编程语言,支持语法高亮、自动换行、自动关闭 HTML 标签等,可同时编辑多个文档。

Bluefish 当然不能算是一款 Python 的 IDE 工具,但如果做 Web 相关的开发( DjanGo、TurboGears 等),用它来写程序显然很方便。而且 Bluefish 相当友好,基本上不用学就会用,可以使我等菜鸟尽快将精力转移到 Python 的学习上来。

Bluefish 官方站在 http://bluefish.openoffice.nl/index.html 目前可以运行在大多数类 UNIX 操作系统上
所谓工欲善其事,必先利其器。Python开发有很多工具,其中Eclipse+Pydev就是其中比较常见的一种。

    下面将开发环境的安装配置过程写下来,供后来者参考。

一、安装Eclipse SDK。

到 http://download.eclipse.org/eclipse/downloads/ 找SDK最新的Release版本,最新的版本是 3.5.1

下载。一开始我选择的是台湾的[Taiwan] National Center for High-Performance Computing (http) ,速度只有5kB/s,还是小日本的快,118kB/S,, Japan Advanced Institute of Science and Technology (http) ,做事情应该也这样,一个明显很缓慢,就要当即力断换其他的。

下载完毕之后,将eclipse SDK解压到某个目录下,我的放在e:\eclipse就可以了。

如果要使用中文的,最好是使用跟SDK配套的语言包,否则也不能完全汉化(最后我选择了纯英文的,没汉化)。根据网上的资料,汉化前不要启动Eclipse,否则不能完全汉化。将语言包也解压到同一目录下即可。

二、安装Pydev

到 http://sourceforge.net/projects/pydev/ 这里找最新版本下载,最新版本是: 1.5.4

下载后解压,将plugins目录下所有文件挪到Eclipse的相应目录下,将feature目录下所有文件挪到Eclipse的相应目录下,最后启动 Eclipse,在Help-》Software Upates-》Manage Configuration,然后弹出的界面即可看到pydev的插件。

另一种安装插件的方法是:Help-》Software Upates-》Find and Install-》Search for new features to install-》New remote site-》随便起个name如pydev,url填 http://pydev.org/updates -》然后照着提示下载安装即可。
这里要注意,官方文档写了一个sf镜像可以用 实际上是不可以用的。

推荐我选择的是后一种方法。

三 、Pydev的配置
在Eclipse IDE 下, 打开 Window->Preferences... 对话框,从右侧的树形列表中选择“ PyDev”->“Interpreter Python”, 点击New按钮,从Python的安装路径下选择Python.exe,然后会弹出一个对话框让你勾选System PYTHONPATH,我是都选了,应该无所谓。最后点Ok,退出。


四、进行Django项目开发

1、建立PyDev Project

Eclipse IDE-》File-》New-》Other-》Pydev-》选择Pydev Project-》起一个项目的名称(例如demo)-》选择路径,如E:\work-》选择适合你的Python版本(我的是2.5)-》将下面的勾去掉,不要建立src文件-》Finish

2、建立Django Project

(1)django-admin.py startproject demo。

(2)把生成的Django项目目录拷贝到Eclipse刚刚建立的项目下的目录里。回到刚才的Elicpse IDE-》在PyDev Package视图中右键单击新建的项目,从弹出的菜单中选择“Refresh”,即可看到Django的项目工程。添加、删除文件和目录的操作都可以通过右键菜单来完成。

(3)右键单击PyDev项目-》属性-》选择PyDev-》PYTHONPATH-》然后将src目录 (项目文件路径) 添加到项目代码中去-》确定


(4)对Pydev项目进行配置:选择Pydev的项目名称-》Run菜单-》Open Run Dialog-》Python Run-》右键New-》在Main面板中写入项目名称,通过Browse载入项目名称和Main Module,Main Module选择manage.py-》在Augement面板中,argument必须是 runserver --noreload,下面的working directory加入你的base directory。

打完收工,接下来开始写Django应用吧。

最后补一个用SourceInsight看Python工程的方法:
1、到http://www.sourceinsight.com/public/languages/下载Python.CLF文件,这是python的语言支持包。
2、打开SourceInsight->Options > Preferences -> Languages -> Import -> Select (.CLF)
3、再做的:-> Document Types - > Add Type (Give it a name : 填Python->.给出类型名:我填的是*.py ) 在下面的下拉框里面选择之前导入的文件,然后确定。Source Insight 就可以识别该类型的文件了。
Tags: , ,

Python sqlite3和单元测试 不指定

zeus , 2010/02/26 10:12 , Python , Comments(0) , Reads(559) , Via Original
import os
import unittest            # 包含单元测试模块
import sqlite3 as sqlite   # 包含sqlite3模块

def get_db_path():
   return "sqlite_testdb"

class TransactionTests(unittest.TestCase):  # 单元测试第一步: 由TestCase派生类
   def setUp(self): # 单元测试环境配置
       try:
           os.remove(get_db_path())
       except:
           pass

       self.con1 = sqlite.connect(get_db_path(), timeout=0.1) # 连接数据库
       self.cur1 = self.con1.cursor() # 获取游标

       self.con2 = sqlite.connect(get_db_path(), timeout=0.1)
       self.cur2 = self.con2.cursor()

   def tearDown(self): # 单元测试环境清除
       self.cur1.close() # 关闭游标
       self.con1.close() # 关闭连接

       self.cur2.close()
       self.con2.close()

       os.unlink(get_db_path())

   def CheckDMLdoesAutoCommitBefore(self):
       self.cur1.execute("create table test(i)") # 执行SQL查询
       self.cur1.execute("insert into test(i) values (5)")
       self.cur1.execute("create table test2(j)")
       self.cur2.execute("select i from test")
       res = self.cur2.fetchall()
       self.failUnlessEqual(len(res), 1) # 测试

   def CheckInsertStartsTransaction(self):
       self.cur1.execute("create table test(i)")
       self.cur1.execute("insert into test(i) values (5)")
       self.cur2.execute("select i from test")
       res = self.cur2.fetchall()
       self.failUnlessEqual(len(res), 0)

   def CheckUpdateStartsTransaction(self):
       self.cur1.execute("create table test(i)")
       self.cur1.execute("insert into test(i) values (5)")
       self.con1.commit()
       self.cur1.execute("update test set i=6")
       self.cur2.execute("select i from test")
       res = self.cur2.fetchone()[0]
       self.failUnlessEqual(res, 5)

   def CheckDeleteStartsTransaction(self):
       self.cur1.execute("create table test(i)")
       self.cur1.execute("insert into test(i) values (5)")
       self.con1.commit()
       self.cur1.execute("delete from test")
       self.cur2.execute("select i from test")
       res = self.cur2.fetchall()
       self.failUnlessEqual(len(res), 1)

   def CheckReplaceStartsTransaction(self):
       self.cur1.execute("create table test(i)")
       self.cur1.execute("insert into test(i) values (5)")
       self.con1.commit()
       self.cur1.execute("replace into test(i) values (6)")
       self.cur2.execute("select i from test")
       res = self.cur2.fetchall()
       self.failUnlessEqual(len(res), 1)
       self.failUnlessEqual(res[0][0], 5)

   def CheckToggleAutoCommit(self):
       self.cur1.execute("create table test(i)")
       self.cur1.execute("insert into test(i) values (5)")
       self.con1.isolation_level = None
       self.failUnlessEqual(self.con1.isolation_level, None)
       self.cur2.execute("select i from test")
       res = self.cur2.fetchall()
       self.failUnlessEqual(len(res), 1)

       self.con1.isolation_level = "DEFERRED"
       self.failUnlessEqual(self.con1.isolation_level , "DEFERRED")
       self.cur1.execute("insert into test(i) values (5)")
       self.cur2.execute("select i from test")
       res = self.cur2.fetchall()
       self.failUnlessEqual(len(res), 1)

   def CheckRaiseTimeout(self):
       self.cur1.execute("create table test(i)")
       self.cur1.execute("insert into test(i) values (5)")
       try:
           self.cur2.execute("insert into test(i) values (5)")
           self.fail("should have raised an OperationalError")
       except sqlite.OperationalError:
           pass
       except:
           self.fail("should have raised an OperationalError")

class SpecialCommandTests(unittest.TestCase):
   def setUp(self):
       self.con = sqlite.connect(":memory:")
       self.cur = self.con.cursor()

   def CheckVacuum(self):
       self.cur.execute("create table test(i)")
       self.cur.execute("insert into test(i) values (5)")
       self.cur.execute("vacuum")

   def CheckDropTable(self):
       self.cur.execute("create table test(i)")
       self.cur.execute("insert into test(i) values (5)")
       self.cur.execute("drop table test")

   def CheckPragma(self):
       self.cur.execute("create table test(i)")
       self.cur.execute("insert into test(i) values (5)")
       self.cur.execute("pragma count_changes=1")

   def tearDown(self):
       self.cur.close()
       self.con.close()

def suite(): # 单元测试第二步
   default_suite = unittest.makeSuite(TransactionTests, "Check")
   special_command_suite = unittest.makeSuite(SpecialCommandTests, "Check")
   return unittest.TestSuite((default_suite, special_command_suite)) # 用例

def test(): # 单元测试第三步
   runner = unittest.TextTestRunner()
   runner.run(suite()) # 运行单元测试

if __name__ == "__main__":
   test()

用python访问sqlite 不指定

zeus , 2010/02/26 10:11 , Python , Comments(0) , Reads(580) , Via Original
1.首先去www.sqlite.org下载一个sqlite,它是一个嵌入式数据库,没有服务器的概念,windows版的就是一个exe,自己把它放到一个合适的目录里,然后把这个目录加入系统的path变量.
2.然后去找个pysqlite,这是python访问sqlite的接口,地址在这里 : http://initd.org/tracker/pysqlite
目前针对不同的python版本,pysqlite有两个版本:2.3和2.4,请根据自己的python版本选用.
3.然后就可以打开自己喜欢的编辑器,写一段测试代码了.
4.中文处理要注意的是sqlite默认以utf-8编码存储.
5.另外要注意sqlite仅支持文件锁,换句话说,它对并发的处理并不好,不推荐在网络环境使用,适合单机环境.
import pysqlite2.dbapi2 as sqlite
   
def runTest():
   cx = sqlite.connect('test.db')
   cu = cx.cursor()
   
   #create
   cu.execute('''create table catalog(
       id integer primary key,
       pid integer,
       name varchar(10) unique
       )''')

   #insert
   cu.execute('insert into catalog values(0,0,"张小山")')
   cu.execute('insert into catalog values(1,0,"hello")')
   cx.commit()
   
   #select
   cu.execute('select * from catalog')
   print '1:',
   print cu.rowcount
   rs = cu.fetchmany(1)
   print '2:',
   print rs
   rs = cu.fetchall()
   print '3:',
   print rs
   
   #delete
   cu.execute('delete from catalog where id = 1 ')
   cx.commit()
   
   
   cu.execute('select * from catalog')
   rs = cu.fetchall()
   print '4:',
   print rs
   
   #select count
   cu.execute("select count(*) from catalog")
   rs = cu.fetchone()
   print '5:',
   print rs
   
   
   cu.execute("select * from catalog")
   cu.execute('drop table catalog')

if __name__ == '__main__':
   runTest()
Pages: 8/67 First page Previous page 3 4 5 6 7 8 9 10 11 12 Next page Final page [ View by Articles | List ]