1.python基础教程(代码编程教学入门)
2.可以在多线程环境中使用mktime和localtime_r吗?
3.python基础教程 10-11例子如何执行
python基础教程(代码编程教学入门)
python入门教程?
给大家整理的这套python学习路线图,按照此教程一步步的学习来,肯定会对python有更深刻的认识。或许可以喜欢上python这个易学,精简,开源的南京互助系统源码语言。此套教程,不但有视频教程,还有源码分享,让大家能真正打开python的大门,进入这个领域。现在互联网巨头,都已经转投到人工智能领域,而人工智能最好的编程语言就是python,未来前景显而易见。黑马程序员是国内最早开设人工智能的机构。
一、首先先推荐一个教程
8天深入理解python教程:
主要讲解,python开发环境的构建,基础的数据类型,字符串如何处理等简单的入门级教程。
二、第二个教程,是系统的基础知识,学习周期大概一个月左右的时间,根据自己的学习能力吸收能力来定。初学者只要跟着此套教程学习,入门完全没有问题。
学完后可掌握的核心能力
1、掌握基本的算命源码漏洞测试Linux系统操作;
2、掌握Python基础编程语法;
3、建立起编程思维和面向对象思想;
可解决的现实问题:
字符串排序,切割,逆置;猜数字、飞机大战游戏;
市场价值:
具备编程思维,掌握Python基本语法,能开发出一些小游戏
所涉及知识点:
教程地址:
三、拓展教程
1、网络爬虫-利用python实现爬取网页神技
第一天:
第二天:
2、Python之web开发利刃
第一天:
第二天:
3、python之大数据开发奇兵
python基础教程
运算
a=
b=
c=0
c=a+b
print"1-c的值为:",c
c=a-b
print"2-c的值为:",c
c=a*b
print"3-c的值为:",c
c=a/b
print"4-c的值为:",c
c=a%b
print"5-c的值为:",c
a=2
b=3
c=a**b
print"6-c的值为:",c
a=
b=5
c=a//b
print"7-c的值为:",c
python比较
a=
b=
c=0
if(a==b):
print"1-a等于b"
else:
print"1-a不等于b"
if(a!=b):
print"2-a不等于b"
else:
print"2-a等于b"
if(ab):
print"3-a不等于b"
else:
print"3-a等于b"
if(ab):
print"4-a小于b"
else:
print"4-a大于等于b"
if(ab):
print"5-a大于b"
else:
print"5-a小于等于b"
a=5
b=
if(a=b):
print"6-a小于等于b"
else:
print"6-a大于b"
if(b=a):
print"7-b大于等于a"
else:
print"7-b小于a"
赋值
a=
b=
c=0
c=a+b
print"1-c的值为:",c
c+=a
print"2-c的值为:",c
c*=a
print"3-c的值为:",c
c/=a
print"4-c的值为:",c
c=2
c%=a
print"5-c的值为:",c
c**=a
print"6-c的值为:",c
c//=a
print"7-c的值为:",c
逻辑运算符:
a=
b=
if(aandb):
print"1-变量a和b都为true"
else:
print"1-变量a和b有一个不为true"
if(aorb):
print"2-变量a和b都为true,或其中一个变量为true"
else:
print"2-变量a和b都不为true"
a=0
if(aandb):
print"3-变量a和b都为true"
else:
print"3-变量a和b有一个不为true"
if(aorb):
print"4-变量a和b都为true,或其中一个变量为true"
else:
print"4-变量a和b都不为true"
ifnot(aandb):
print"5-变量a和b都为false,或其中一个变量为false"
else:
print"5-变量a和b都为true"
in,notin
a=
b=
list=[1,2,3,4,5];
if(ainlist):
print"1-变量a在给定的列表中list中"
else:
print"1-变量a不在给定的列表中list中"
if(bnotinlist):
print"2-变量b不在给定的列表中list中"
else:
print"2-变量b在给定的列表中list中"
a=2
if(ainlist):
print"3-变量a在给定的列表中list中"
else:
print"3-变量a不在给定的列表中list中"
条件
flag=False
name='luren'
ifname=='python':#判断变量否为'python'
flag=True#条件成立时设置标志为真
print'welcomeboss'#并输出欢迎信息
else:
printname
num=5
ifnum==3:#判断num的值
print'boss'
elifnum==2:
print'user'
elifnum==1:
print'worker'
elifnum0:#值小于零时输出
print'error'
else:
print'roadman'#条件均不成立时输出
循环语句:
count=0
while(count9):
print'Thecountis:',count
count=count+1
print"Goodbye!"
i=1
whilei:
i+=1
ifi%:#非双数时跳过输出
continue
printi#输出双数2、4、6、8、
i=1
while1:#循环条件为1必定成立
printi#输出1~
i+=1
ifi:#当i大于时跳出循环
break
forletterin'Python':#第一个实例
print'当前字母:',letter
fruits=['banana','apple','mango']
forfruitinfruits:#第二个实例
print'当前水果:',fruit
print"Goodbye!"
获取用户输入:raw_input
var=1
whilevar==1:#该条件永远为true,循环将无限执行下去
num=raw_input("Enteranumber:")
print"Youentered:",num
print"Goodbye!"
range,len
fruits=['banana','apple','mango']
forindexinrange(len(fruits)):
print'当前水果:',fruits[index]
print"Goodbye!"
python数学函数:
abs,cell,cmp,exp,fabs,floor,log,log,max,min,mod,pow,round,sqrt
randrange
访问字符串的值
var1='HelloWorld!'
var2="PythonRunoob"
print"var1[0]:",var1[0]
print"var2[1:5]:",var2[1:5]
转义字符
格式化输出
print"Mynameis%sandweightis%dkg!"%('Zara',)
字符串函数:
添加元素
list=[]##空列表
list.append('Google')##使用append()添加元素
list.append('Runoob')
printlist
删除元素
list1=['physics','chemistry',,]
printlist1
dellist1[2]
print"Afterdeletingvalueatindex2:"
printlist1
列表操作
列表方法
删除字典
dict={ 'Name':'Zara','Age':7,'Class':'First'};
deldict['Name'];#删除键是'Name'的条目
dict.clear();#清空词典所有条目
deldict;#删除词典
print"dict['Age']:",dict['Age'];
print"dict['School']:",dict['School'];
字典的函数:
当前时间戳:
importtime
time.time()
格式化日期输出
importtime
printtime.strftime("%Y-%m-%d%H:%M:%S",time.localtime())
printtime.strftime("%a%b%d%H:%M:%S%Y",time.localtime())
a="SatMar::"
printtime.mktime(time.strptime(a,"%a%b%d%H:%M:%S%Y"))
获取某个月日历:calendar
importcalendar
cal=calendar.month(,1)
print"以下输出年1月份的日历:"
printcal
当前日期和时间
importdatetime
i=datetime.datetime.now()
print("当前的日期和时间是%s"%i)
print("ISO格式的日期和时间是%s"%i.isoformat())
print("当前的年份是%s"%i.year)
print("当前的月份是%s"%i.month)
print("当前的日期是%s"%i.day)
print("dd/mm/yyyy格式是%s/%s/%s"%(i.day,i.month,i.year))
print("当前小时是%s"%i.hour)
print("当前分钟是%s"%i.minute)
print("当前秒是%s"%i.second)
不定长参数:
*lambda:匿名函数
def....
python模块搜索路径
获取用户输入
str=raw_input("请输入:")
print"你输入的内容是:",str
input可以接收表达式
open参数
write要自己添加换行符
读取个字符
重命名:os.rename
os.remove
os.mkdiros.chdir
os.getcwd
os.rmdir
open参数
file的方法
异常:
try:
fh=open("testfile","w")
fh.write("这是一个测试文件,用于测试异常!!")
exceptIOError:
print"Error:没有找到文件或读取文件失败"
else:
print"内容写入文件成功"
fh.close()
try:
fh=open("testfile","w")
fh.write("这是一个测试文件,用于测试异常!!")
finally:
print"Error:没有找到文件或读取文件失败"
用户自定义异常:
os模块提供了非常丰富的方法用来处理文件和目录。常用的方法如下表所示:
|序号|方法及描述|
|1|
os.access(path,mode)
检验权限模式|
|2|
os.chdir(path)
改变当前工作目录|
|3|
os.chflags(path,flags)
设置路径的标记为数字标记。|
|4|
os.chmod(path,mode)
更改权限|
|5|
os.chown(path,uid,gid)
更改文件所有者|
|6|
os.chroot(path)
改变当前进程的根目录|
|7|
os.close(fd)
关闭文件描述符fd|
|8|
os.closerange(fd_low,fd_high)
关闭所有文件描述符,从fd_low(包含)到fd_high(不包含),错误会忽略|
|9|
os.dup(fd)
复制文件描述符fd|
||
os.dup2(fd,fd2)
将一个文件描述符fd复制到另一个fd2|
||
os.fchdir(fd)
通过文件描述符改变当前工作目录|
||
os.fchmod(fd,mode)
改变一个文件的访问权限,该文件由参数fd指定,参数mode是Unix下的文件访问权限。|
||
os.fchown(fd,uid,gid)
修改一个文件的所有权,这个函数修改一个文件的用户ID和用户组ID,该文件由文件描述符fd指定。在线测试Ai源码|
||
os.fdatasync(fd)
强制将文件写入磁盘,该文件由文件描述符fd指定,但是不强制更新文件的状态信息。|
||
os.fdopen(fd[,mode[,bufsize]])
通过文件描述符fd创建一个文件对象,并返回这个文件对象|
||
os.fpathconf(fd,name)
返回一个打开的文件的系统配置信息。name为检索的系统配置的值,它也许是一个定义系统值的字符串,这些名字在很多标准中指定(POSIX.1,Unix,Unix,和其它)。|
||
os.fstat(fd)
返回文件描述符fd的状态,像stat()。|
||
os.fstatvfs(fd)
返回包含文件描述符fd的文件的文件系统的信息,像statvfs()|
||
os.fsync(fd)
强制将文件描述符为fd的文件写入硬盘。|
||
os.ftruncate(fd,length)
裁剪文件描述符fd对应的文件,所以它最大不能超过文件大小。|
||
os.getcwd()
返回当前工作目录|
||
os.getcwdu()
返回一个当前工作目录的Unicode对象|
||
os.isatty(fd)
如果文件描述符fd是打开的,同时与tty(-like)设备相连,则返回true,否则False。|
||
os.lchflags(path,flags)
设置路径的标记为数字标记,类似chflags(),但是没有软链接|
||
os.lchmod(path,mode)
修改连接文件权限|
||
os.lchown(path,uid,gid)
更改文件所有者,类似chown,但是不追踪链接。|
||
os.link(src,dst)
创建硬链接,名为参数dst,指向参数src|
||
os.listdir(path)
返回path指定的文件夹包含的文件或文件夹的名字的列表。|
||
os.lseek(fd,pos,how)
设置文件描述符fd当前位置为pos,how方式修改:SEEK_SET或者0设置从文件开始的计算的pos;SEEK_CUR或者1则从当前位置计算;os.SEEK_END或者2则从文件尾部开始.在unix,Windows中有效|
||
os.lstat(path)
像stat(),但是没有软链接|
||
os.major(device)
从原始的设备号中提取设备major号码(使用stat中的st_dev或者st_rdevfield)。|
||
os.makedev(major,minor)
以major和minor设备号组成一个原始设备号|
||
os.makedirs(path[,mode])
递归文件夹创建函数。像mkdir(),但创建的所有intermediate-level文件夹需要包含子文件夹。|
||
os.minor(device)
从原始的如何查网址源码设备号中提取设备minor号码(使用stat中的st_dev或者st_rdevfield)。|
||
os.mkdir(path[,mode])
以数字mode的mode创建一个名为path的文件夹.默认的mode是(八进制)。|
||
os.mkfifo(path[,mode])
创建命名管道,mode为数字,默认为(八进制)|
||
os.mknod(filename[,mode=,device])
创建一个名为filename文件系统节点(文件,设备特别文件或者命名pipe)。
|
||
os.open(file,flags[,mode])
打开一个文件,并且设置需要的打开选项,mode参数是可选的|
||
os.openpty()
打开一个新的伪终端对。返回pty和tty的文件描述符。|
||
os.pathconf(path,name)
返回相关文件的系统配置信息。|
||
os.pipe()
创建一个管道.返回一对文件描述符(r,w)分别为读和写|
||
os.popen(command[,mode[,bufsize]])
从一个command打开一个管道|
||
os.read(fd,n)
从文件描述符fd中读取最多n个字节,返回包含读取字节的字符串,文件描述符fd对应文件已达到结尾,返回一个空字符串。|
||
os.readlink(path)
返回软链接所指向的文件|
||
os.remove(path)
删除路径为path的文件。如果path是一个文件夹,将抛出OSError;查看下面的rmdir()删除一个directory。|
||
os.removedirs(path)
递归删除目录。|
||
os.rename(src,dst)
重命名文件或目录,从src到dst|
||
os.renames(old,new)
递归地对目录进行更名,也可以对文件进行更名。|
||
os.rmdir(path)
删除path指定的空目录,如果目录非空,则抛出一个OSError异常。|
||
os.stat(path)
获取path指定的
可以在多线程环境中使用mktime和localtime_r吗?
localtime和mktime是用于在时间分量和时间秒数之间转换的标准c函数.
在glibc文档描述中,localtime的实现使用内部静态缓存来保存结果,因此这是一个API,不适用于多线程环境. glibc提供了线程安全的localtime_r版本. mktime没有这个问题.
因此,根据glibc文档,在多线程环境中使用localtime_r和mktime是鼠茅溯源码安全的localtime 线程安全。
mktime和localtime_r的实现都考虑了时区的转换,并且时区的计算应使用全局变量tzname / timezone / daylight. 这本质上是线程不安全的.
请参阅glibc-2.3.2的源代码(下面的源代码位置均相对于源目录)
--------- time / localtime.c和time / tzset.c
在localtime_r中,调用tzset_internal来设置时区. 输入参数始终为0,因此从理论上讲,只要第一次结束,就无需初始化. 请参阅下面的代码.
但是,由于在多线程环境中引入了静态变量is_initialized,因此该实现代码存在问题. 无法保证并发执行环境的正确性.
----(时间/ tzset.c)-------
/ *解释TZ变量. * /
静态无效
内部功能
tzset_internal(始终)
int始终;
{
static int is_initialized;
注册const char * tz;
寄存器size_t l;
char * tzbuf;
unsigned short int hh,mmlocaltime 线程安全,ss;
无符号短整数规则;
如果(始终被is_initialized &&!)
返回;
is_initialized = 1;
.
}
但是mktime不是这样的
----(时间/ mktime.c)-------
/ *将* TP转换为time_t值. * /
time_t
mktime(tp)
struct tm * tp;
{
#ifdef _LIBC
/ * POSIX.1 8.1.1要求,每当调用mktime()时。
外部变量`tzname'中包含的
时区名称
设置
就像调用tzset()函数一样. * /
__ tzset();
#endif
返回__mktime_internal(tp,my_mktime_localtime_r和localtime_offset);
}
由于定义了_LIBC,每次都会调用tzset,因此tzset的代码是这样的
----(时间/ tzset.c)-------
无效
__ tzset(无效)
{
__ libc_lock_lock(tzset_lock);
tzset_internal(1);
如果(!____ use_tzfile)
{
/ *设置`tzname'. * /
__ tzname [0] =(char *)tz_rules [0] .name;
__ tzname [1] =(char *)tz_rules [1] .name;
}
__ libc_lock_unlock(tzset_lock);
}
每次都会调用tzset_internal,并且每次都将重写时区信息.
应注意,前面的宏__libc_lock_lock在sysdeps / generic / bits / libc-lock.h中定义为:
#define __libc_lock_lock(名称)
是无操作操作,因此它不能用作同步线程.
因此,您可以看到上述glibc代码实现中存在两个问题:
1. tzset_internal is_initialized中使用的静态变量
(这可以通过在程序中定义一个无用的全局变量并程开始工作之前在其初始化中调用mktime来克服)
2. mktime必须每次都重写全局变量tzname / timezone / daylight
(这个问题基本上是没有办法解决的)
因此mktime和localtime_r不适合多线程应用程序.
有两种解决方案:
1. 自己实现mktime和localtime_r,但是时区的计算很麻烦. 当然,您不能使用时区信息,也不能使用固定时区,例如北京时区.
2. 使用pthread的互斥锁来锁定mktime和localtime_r,但是以这种方式使用pthread库,可移植性不够好.
python基础教程 -例子如何执行
. 模块相关Python的标准安装包包括一组模块,称为标准库(standard library)。
.1 模块
.1.1 模块是程序
# hello.pyprint "Hello, world!"# 保存放在C:\python# 告诉解释器在哪里寻找模块>>> import sys>>> sys.path.append('c:/python')# 这样,解释器除了从默认的目录中寻找之外,还需要从目录c:\python中寻找模块>>> import hello
Hello, world!
导入模块多次和导入一次的效果是一样的。如果坚持重新载入模块,可以使用内建的reload函数。
.1.2 模块用于定义
在模块中定义函数
# hello2.pydef hello():
print "Hello, world# 使用import hello2
hello2.hello()
在模块中增加测试代码
为 “告知” 模块本身是作为程序运行还是导入到其他程序,需要使用__name__变量:
# hello4.pydef hello():
print "Hello, world!"def test():
hello()if __name__ == '__main__': test()
.1.3 让模块可用
将模块放置在正确位置
# 下面命令列出的路径都可以放置,但site-packages目录是最佳选择>>> import sys, pprint>>> pprint.pprint(sys.path)
告诉编译器去哪里找
除了编辑sys.path外,更通用的方法是设置环境变量PYTHONPATH
.1.4 包
当模块存储在文件中时(扩展名.py),包就是模块所在的目录。为了让Python将其作为包对待,它必须包含一个命名为__init__py的文件(模块)。如果将它作为普通模块导入的话,文件的内容就是包的内容。
vim constants/__init__.py
PI=3.# 别的地方引用import constantsprint constants.PI
.2 探究模块
.2.1 模块中有什么
使用dir
查看模块包含的内容,它会将对象(以及模块的所有函数、类、变量等)的所有特性列出。
# 导入模块
import copy# 列表推导式是个包含dir(copy)中所有不以下划线开头的名字的列表。
[n for n in dir(copy)] if not n.startwith('_')]
__all__变量
这个变量包含一个列表,该列表与上一节的列表类似。
copy.__all__1
它定义了模块的共有接口,在编写模块的时候,像设置__all__这样的技术是相当有用的。
__all__ = ["Error", "copy", "deepcopy"]1
.2.2 用help获取帮助
使用help函数,获得帮助文本。
help(copy.copy)1
.2.3 文档
参考
.2.4 使用源代码
方案一:检查sys.path,然后自己找。
方案二:检查模块的__file__属性
.3 标准库
.3.1 sys
sys这个模块能够访问与Python解释器联系紧密的变量和函数。部分重要函数和变量如下:
函数/变量
描述
argv 命令行参数,包括传递到Python解释器的参数,脚本名称
exit([arg]) 退出当前的程序,可选参数为给定的返回值或错误信息
modules 映射模块名字到载入模块的字典
path 查找模块所在目录的目录名列表
platform 类似sunos5或win的平台标识符
stdin 标准输入流——一个类文件(file-like)对象
stdout 标准输出流
stderr 标准错误流
.3.2 os
os模块提供了访问多个操作系统服务的功能。下表列出一些最有用的函数和变量。另外,os和它的子模块os.path还包含一些用于检查、构造、删除目录和文件的函数,以及一些处理路径的函数(例如,os.path.split和os.path.join让你在大部分情况下都可以忽略os.pathsep)。
函数/变量
描述
environ 对环境变量进行映射
system(command) 在子shell中执行操作系统命令
sep 路径中的分隔符
pathsep 分隔路径的分隔符
linesep 行分隔符
urandom(n) 返回n个字节的加密强随机数据
.3.3 fileinput
fileinput模块能够轻松地遍历文本文件的所有行。
函数/变量
描述
input([files[, inplace[, backup]]]) 便于遍历多个输入流中的行
filename() 返回当前文件的名称
lineno() 返回当前(累计)的行数
filelineno() 返回当前文件的行数
isfirstline() 检查当前行是否是文件的第一行
isstdin() 检查最后一行是否来自sys.stdin
nextfile() 关闭当前文件,移动到下一个文件
close() 关闭序列
为Python脚本添加行号
# numberlines.pyimport fileinputfor line in fileinput.input(inplcae=True) line = line.rstrip() num = fileinput.lineno()
print '%-s # %2i' % (line, num)
.3.4 集合、堆和双端队列
集合
Set类位于sets模块中。非重复、无序的序列。
堆
堆(heap)是优先队列的一种。使用优先队列能够以任意顺序增加对象,并且能在任何时间找到最小的元素,也就是说它比用于列表的min方法要有效率得多。下面是heapq模块中重要的函数:
函数
描述
heappush(heap, x) 将x入堆
heappop(heap) 将堆中最小的元素弹出
heapify(heap) 将heap属性强制应用到任意一个列表,将其转换为合法的堆
heapreplace(heap, x) 将堆中最小的元素弹出,同时将x入堆
nlargest(n, iter) 返回iter中第n大的元素
nsmallest(n, iter) 返回iter中第n小的元素
元素虽然不是严格排序的,但是也有规则:i位置处的元素总比2*i以及2*i+1位置处的元素小。这是底层堆算法的基础,而这个特性称为堆属性(heap property)。
双端队列(以及其他集合类型)
双端队列(Double-ended queue)在需要按照元素增加的顺序来移除元素时非常有用。它能够有效地在开头增加和弹出元素,这是在列表中无法实现的,除此之外,使用双端队列的好处还有:能够有效地旋转(rotate)元素。deque类型包含在collections模块。
.3.5 time
time模块所包含的函数能够实现以下功能:获得当前时间、操作时间和日期、从字符串读取时间以及格式化时间为字符串。日期可以用实数或者包含有9个整数的元组。元组意义如下:
索引
字段
值
0 年 比如等
1 月 范围1~
2 日 范围1~
3 时 范围0~
4 分 范围0~
5 秒 范围0~(应付闰秒和双闰秒)
6 周 当周一为0时,范围0~6
7 儒历日 范围1~
8 夏令日 0、1、-1
time的重要函数:
函数
描述
asctime([tuple]) 将时间元组转换为字符串
localtime([secs]) 将秒数转换为日期元组,以本地时间为准
mktime(tuple) 将时间元组转换为本地时间
sleep(secs) 休眠secs秒
strptime(string[, format]) 将字符串解析为时间元组
time() 当前时间(新纪元开始后的秒数,以UTC为准)
.3.6 random
random模块包括返回随机数的函数,可以用于模拟或者用于任何产出随机输出的程序。
如果需要真的随机数,应该使用os模块的urandom函数。random模块内的SystemRandom类也是基于同样功能。
函数
描述
random() 返回0 <= n < 1之间的随机实数n,其中0 < n <=1
getrandbits(n) 以长整型形式返回n个随机位
uniform(a, b) 返回随机实数n,其中 a <= n < b
randrange([start], stop, [step]) 返回range(start, stop, step)中的随机数
choice(seq) 从序列seq中返回随机元素
shuffle(seq[, random]) 原地指定序列seq
sample(seq, n) 从序列seq中选择n个随机且独立的元素
示例一:
from random import *from time import
*date1 = (, 1, 1, 0, 0, 0, -1, -1, -1)
time1 = mktime(date1)
date2 = (, 1, 1, 0, 0, 0, -1, -1, -1)
time2 = mktime(date2)
random_time = uniform(time1, time2)print asctime(localtime(random_time))
.3.7 shelve
提供一个存储方案。shelve的open函数返回一个Shelf对象,可以用它来存储内容。只需要把它当做普通的字典来操作即可,在完成工作之后,调用close方法。
import shelve
s = shelve.open('test.dat')
s['x'] = ['a', 'b', 'c']# 下面代码,d的添加会失败# s['x'].append('d')# s['x']# 正确应该使用如下方法:temp = s['x']
temp.append('d')
s['x'] = temp
.3.8 re
re模块包含对正则表达式的支持。
正则表达式
.号只能匹配一个字符(除换行符外的任何单个字符)。
\为转义字符
字符集:使用[]括起来,例如[a-zA-Z0-9],使用^反转字符集
选择符(|)和子模式():例如'p(ython|erl)'
可选项(在子模式后面加上问号)和重复子模式:例如r'(pile(pattern[, flags]) 根据包含正则表达式的字符串创建模式对象
search(pattern, string[, flags]) 在字符串中寻找模式
match(pattern, string[, flags]) 在字符串的开始处匹配模式
split(pattern, string[, maxsplit=0]) 根据模式的匹配项来分隔字符串
findall(pattern, string) 列出字符串中模式的所有匹配项
sub(pat, repl, string[, count=0]) 将字符串中所有pat的匹配项用repl替换
escape(string) 将字符串中所有特殊正则表达式字符转义
匹配对象和组
对于re模块中那些能够对字符串进行模式匹配的函数而言,当能找到匹配项时,返回MatchObject对象。包含了哪个模式匹配了子字符串的哪部分的信息。——这些“部分”叫做组。
组就是放置在圆括号内的子模式。组的序号取决于它左侧的括号数。组0就是整个模式。
re匹配对象的一些方法:
方法
描述
group([group1, …]) 获取给定子模式(组)的匹配项
start([group]) 返回给定组的匹配项的开始位置
end([group]) 返回给定组的匹配项的结束位置(和分片一样,不包括组的结束位置)
span([group]) 返回一个组的开始和结束位置
作为替换的组号和函数
示例:假设要把'*something*'用<em>something</em>替换掉:
emphasis_pattern = r'\*([^\*]+)\*'# 或者用VERBOSE标志加注释,它允许在模式中添加空白。emphasis_pattern = re.compile(r'''\* # 开始的强调标签
( # 组开始
[^\*]+ # 除了星号的所有字符
) # 组结束
\* # 结束的强调标签
''', re.VERBOSE)
re.sub(emphasis_pattern, r'<em>\1</em>', 'Hello, *world*!')# 结果'Hello, <em>world</em>!'
找出Email的发信人# 示例一# 匹配内容:From: Foo Fie <foo@bar.baz># find_sender.pyimport fileinput, repat = re.compile('From: (.*) <.*?>$')for line in fileinput.input():
m = pat.match(line) if m: print m.group(1)# 执行$ python find_sender.py message.eml# 示例二# 列出所有Email地址import fileinput, re
pat = re.compile(r'[a-z\-\.]+@[a-z\-\.]+', re.IGNORECASE)
addresses = set()for line in fileinput.input(): for address in pat.findall(line):
addresses.add(address)for address in sorted(addresses): print address
模板系统示例模板是一种通过放入具体值从而得到某种已完成文本的文件。
示例:把所有'[somethings]'(字段)的匹配项替换为通用Python表达式计算出来的something结果
'The sum of 7 and 9 is [7 + 9].'应该翻译成'The sum of 7 and 9 is .'
同时,可以在字段内进行赋值
'[name="Mr. Gumby"]Hello, [name]'
应该翻译成'Hello, Mr. Gumby'
代码如下# templates.py#!/usr/bin/python# -*- coding: utf-8 -*-import fileinput, re# 匹配中括号里的字段field_pat = re.compile(r'\[(.+?)\]')# 我们将变量收集到这里scope = { }# 用于re.sub中def replacement(match):code = match.group(1) try: # 如果字段可以求值,返回它:
return str(eval(code, scope)) except SyntaxError: # 否则执行相同作用域内的赋值语句......
exec code in scope # ......返回空字符串
return ''# 将所有文本以一个字符串的形式获取lines = []for line in fileinput.input():
lines.append(line)
text = ''.join(lines)# 将field模式的所有匹配项都替换掉print field_pat.sub(replacement, text)
.3.9 其他标准模块functools:能够通过部分参数来使用某个函数(部分求值),稍后再为剩下的参数提供数值。
difflib:可以计算两个序列的相似程度。还能从一些序列中(可供选择的序列列表)找出和提供的原始序列“最像”的那个。可以用于创建简单的搜索程序。
hashlib:可以通过字符串计算小“签名”。
csv:处理CSV文件
timeit、profile和trace:timeit(以及它的命令行脚本)是衡量代码片段运行时间的工具。它有很多神秘的功能,应该用它代替time模块进行性能测试。profile模块(和伴随模块pstats)可用于代码片段效率的全面分析。trace模块(和程序)可以提供总的分析(覆盖率),在写测试代码时很有用。
datetime:支持特殊的日期和时间对象,比time的接口更直观。
itertools:有很多工具用来创建和联合迭代器(或者其他可迭代对象),还包括实现以下功能的函数:将可迭代的对象链接起来、创建返回无限连续整数的迭代器(和range类似,但没有上限),从而通过重复访问可迭代对象进行循环等等。
logging:输出日志文件。
getopt和optparse:在UNIX中,命令行程序经常使用不同的选项或开关运行。getopt为解决这个问题的。optparse则更新、更强大。
cmd:可以编写命令行解释器。可以自定义命令。
.4 新函数
函数
描述
dir(obj) 返回按字母顺序排序的属性名称列表
help([obj])
reload(module)
. 文件
.1 打开文件
open函数用来打开文件,语法如下:
open(name[, mode[, buffering]])1 .1.1 文件模式默认只读打开。
值
描述
‘r’ 读模式
‘w’ 写模式
‘a’ 追加模式
‘b’ 二进制模式(可添加到其他模式中使用)
‘+’ 读/写模式(可添加到其他模式中使用)
.1.2 缓存
open函数的第三个参数(可选)控制文件的缓冲。有缓冲时,只有使用flush或close时才会更新硬盘上的数据。
值
描述
0或False 无缓冲
1或True 有缓冲
大于1的数字 缓冲区大小(字节)
-1或负数 默认的缓冲区大小
.2 基本文件方法
.2.1 读和写
>>> f = open('somefile.txt', 'w')>>> f.write('Hello, ')>>> f.write('World!')>>> f.close()>>> f = open('somefile.txt', 'r')>>> f.read(4) # 读取的字符数(字节)'Hell'>>> f.read()'o, World!' .2.2 管式输出# somescript.pyimport systext = sys.stdin.read()words = text.split()wordcount = len(words)