一、日志:Logging
import logging
fmt = '%(asctime)s - %(filename)s:%(lineno)s - %(name)s - %(message)s'
# 时间-文件名:行数-logger名-日志信息
logging.basicConfig(level=logging.DEBUG, filename='testLog.log', format=fmt)
log = logging.getLogger('testLog')
log.debug('Starting program!')
# 2017-12-08 14:51:13,420 - Log.py:11 - testLog - Starting program!
二、配置文件:ConfigParser
标准库模块ConfigParser,它的作用是对配置文件使用适当的标准格式。需要使用[files]或者[colors]这样的数据头将配置文件划分为几个区段
from ConfigParser import SafeConfigParser
config = SafeConfigParser()
# 读取配置文件,当配置文件不存在时会自动创建
config.read('my.conf')
# 如果没有section,则先创建
if not config.has_section('redis'):
config.add_section('redis')
if not config.has_section('mysql'):
config.add_section('mysql')
# 设置或者更新值
config.set('redis', 'host', '192.168.6.188')
config.set('redis', 'ip', '22121')
config.set('mysql', 'ip', '192.168.6.186')
# 将更新写入文件
with open('my.conf', 'w') as c:
config.write(c)
# 获取需要的区段内容
host = config.get('mysql', 'ip')
print host
三、对象串行化:cPickle
pickle模块实现了一个算法可以将一个任意的Python对象转换为一系列字节。这个过程也称为串行化对象。表示对象的字节流可以传输或存储,然后重新构造来创建相同性质的新对象。cPickle用C实现的同样算法,比pickle快数倍。
import cPickle
map1 = {'name': 'regan', 'age': 24, 'gender': 'male'}
# 写pkl文件
with open('my.pkl', 'w') as p:
cPickle.dump(map1, p)
# 读pkl文件
with open('my.pkl', 'r') as p:
map2 = cPickle.load(p)
print map2
# {'gender': 'male', 'age': 24, 'name': 'regan'}
四、路径:os.path
import os, sys
realpath = os.path.realpath(__file__) # __file__代表当前文件,realpath()得到绝对路径
dirname = os.path.dirname(realpath) # dirname()将绝对路径进行分割,得到当前文件所在的目录
ddirname = os.path.dirname(dirname) # 将dirname进行分割,得到当前文件所在目录的上层目录
sys.path.append(ddirname)
# sys.path是一个列表,保存了所有与当前文件相关的路径,将ddirname加入其中以便系统定位当前文件所在目录的父目录
configpath = os.path.join(ddirname, 'basic2', 'Map.py')
# 使用正确的分隔符将数个路径连接起来(比如在UNIX内使用/等)。
os.makedirs('foo/bar/baz')
# 在当前的目录中创建foo目录,然后在foo中创建bar目录,最后在bar目录内创建baz。如果所有目录都存在,则会引发一个异常
print os.path.isdir(__file__) # False, 检查给定的路径是否是目录(即目录是否存在)
print os.path.isdir(ddirname) # True
五、时间:Time
import time
# 日期可以用实数,或者是包含有9个整数的元组。比如,元组:(2017,9,29,21,35,00,4,191,0)
# time() 当前时间(新纪元开始后的秒数)
print time.time() # 1506692473.2
# 函数asctime()将当前时间格式化为字符串
print time.asctime() # Fri Sep 29 21:36:10 2017
print time.asctime((2017, 9, 29, 21, 35, 00, 4, 191, 0)) # 将时间元组转换为字符串
# localtime(secs) 将秒数转换为日期元组,以本地时间为准
print time.localtime(1493464)
# time.struct_time(tm_year=1970, tm_mon=1, tm_mday=18, tm_hour=14, tm_min=51, tm_sec=4, tm_wday=6, tm_yday=18, tm_isdst=0)
# mktime(tuple) 将时间元组转换为用秒计的本地时间
print time.mktime((2017, 9, 29, 21, 35, 00, 4, 191, 0)) # 1506692100.0
# sleep(secs) 休眠secs秒
time.sleep(2)
# strptime(string,[format]) 将字符串解析为时间元组
from datetime import datetime
print datetime.now().strftime('%Y-%m-%d %H:%M:%S') # 2017-12-08 16:38:29, 将time格式化为字符串
d = datetime.strptime('2012-03-01 12:06:23', '%Y-%m-%d %H:%M:%S') # 2012-03-01 12:06:23, 将字符串转化为指定格式的time
print d.date() # 2012-03-01
print d.day # 1
六、文件操作:Open
打开文件:open(file=,mode=,buffering=)
文件模式mode: r 读 ; w 写 ; + 读/写 ; a 追加模式 ; b 二进制模式
参数’rb’可以用来读取一个二进制文件。
缓冲:buffer
如果参数是0 (或者是False), I/O 就是无缓冲的(所有的读写操作都直接针对硬盘)
如果是1(或者是True), I/O 就是有缓冲的(意味着python使用内存来代替硬盘,让程序更快,只有使用flush或者close时才会更新硬盘上的数据)。
大于1的数字代表缓冲区的大小(单位是字节),-1 (或者是任何负数)代表使用默认的缓冲区大小。
with open('my.txt', 'a', -1) as test:
test.write('regan!\n') # 写一行
test.writelines(['lily!\n', 'lucy!\n']) # 写多行
with open('my.txt', 'r') as test:
print test.readline() # 每次读取一行内容
test.seek(0) # 将偏移量移动到文件开头。seek(offset,whence),whence默认为0,即偏移量是从文件开头计算。1表示相对于当前位置的移动,2表示相对于文件结尾的移动。
print test.readlines() # 读取所有内容,返回列表。['hello regan!\n', 'hello regan!\n']
# 使用fileinput实现懒惰行迭代
# 在需要对一个非常大的文件进行迭代行的操作肘, readlines会占用太多的内存。这个时候可以使用while循环和readline方法来替代。
import fileinput
for line in fileinput.input('my.txt'):
print line
七、异常:Exception
① raise , 手动抛出异常中断程序
def myExcept(name):
if name != 'regan':
raise Exception('your name is not regan , please try agin!')
myExcept('lucy') # 将输出: Exception: your name is not regan , please try agin!
② 捕捉异常
# 如果需要用一个块捕捉多个类型异常,那么可以将它们作为元组列出
try:
1 / 0
except (AssertionError, ZeroDivisionError, BytesWarning):
pass
# 捕捉所有异常,并打印
try:
1 / 0
except Exception, e:
print e # integer division or modulo by zero
# 如果希望在except子句中访问异常对象本身,可以使用两个参数(注意,就算要捕捉到多个异常,也只需向except子句提供一个参数一一一个元组)。
try:
1 / 0
except (AssertionError, ZeroDivisionError, BytesWarning), e:
print e # integer division or modulo by zero
③ else子句:如果未发生异常,则执行else子句内容。
try:
1 / 7
except Exception, e:
print e
else:
print 'there has some plan !' # there has some error !
④ finally子句
try:
1 / 0
except Exception, e:
print e
finally:
print 'ending!' # ending!
# finally模块一定会被执行,因此可用于关闭连接等重要的工作
八、Md5
计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。
import hashlib, os, sys
dir = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.dirname(dir))
① 求字符串的MD5
rawString = u'被用于计算的原始字符串'
md5 = hashlib.md5(rawString.encode('utf8')).hexdigest()
print(md5)
② 求文件MD5
filePath = os.path.join(dir, 'testMD5.txt')
with open(filePath, 'rb') as f:
md5 = hashlib.md5(f.read()).hexdigest()
print(md5)
九、随机数:random
如果需要真的随机性,应该使用OS模块的urandom函数.
random模块内的SystemRandom类也是基于同种功能,可以让数据接近真正的随机性。
import random
① random() 返回O到1之间的随机实数n,其中0< n <= 1
print random.random() # 0.347799216277
② getrandbits() 以长整型形式返回给定的位数(二进制数)。
如果处理的是真正的随机事务(比如加密),这个函数尤为有用。
print random.getrandbits(3) # 6
③ uniform(a,b) 提供两个数值参数a和b,返回在a~b的随机(平均分布的)实数n。
所以,比如需要随机的角度值,可以使用uniform(0.360)。
print random.uniform(0, 360) # 78.2772699052
④ randrange([start],stop. [step]) 返回range(start.stop.step)中的随机数
print random.randrange(5, 100, 8) # 77
⑤ choice() 从给定序列中(均一地)选择随机元素。
print random.choice([2, 45, 56, 23, 8]) # 23
print random.choice(['regan', 'age', 'hah']) # regan
⑥ sample从给定序列中(均一地)选择给定数目的元素,同时确保元素互不相同。
print random.sample([1, 2, 3, 45, 6], 2) # [1, 2]
”’
十、正则:Re
import re
① compile() 将正则表达式(以字符串书写的)转换为模式对象,可以实现更有效率的匹配
module = re.compile('regan*', flags=0)
② search() 会在给定字符串中寻找第一个匹配给定正则表达式的子字符串。一但找到子字符串,函数就会返回MatchObject(值为True ),否则返回None(值为False )。
print re.search(module, 'helloreganlucy') # <_sre.SRE_Match object at 0x000000000465A510>
③ match() 会在给定字符串的开头匹配正则表达式。
print re.match('p', 'python') # <_sre.SRE_Match object at 0x0000000004A1A510>
print re.match('p', 'www.python.com') # None
④ split() 会根据模式的匹配项来分割字符串。它类似于字符串方法split ,不过是用完整的正则表达式代替了固定的分隔符字符串。
test = 'regan.lucy...age.name'
print re.split('[. ]+', test, maxsplit=2) # ['regan', 'lucy', 'age.name']
print re.split('[. ]+', test, maxsplit=3) # ['regan', 'lucy', 'age', 'name']
⑤ findall() 以列表形式返回给定模式的所有匹配项。比如,要在字符串中查找所有的单词,可以像下面这么做:
print re.findall('a..', test) # ['an.', 'age', 'ame']
⑥ sub() 使用给定的替换内容将匹配模式的子字符串(最左端并且非重叠的子字符串)替换掉
print re.sub('a.', 'regan', test, 2) # regregan.lucy...regane.name
⑦ escape() 对字符串中所有可能被解释为正则运算符的字符进行转义
print re.escape('www.python.org') # www\.python\.org
⑧ 匹配对象和组
组就是放置在圆括号内的子模式。组的序号取决于它左侧的括号数。组0就是整个模式
‘There (was a (wee) (cooper)) who (lived in Fyfe)’
包含下面这些组:
0 There was a wee cooper who lived in Fyfe
1 was a wee cooper
2 wee
3 cooper
4 lived in Fyfe
m = re.match(r'www\.(.*)\..{3}','www.python.org')
print m.group(1) # python
print m.start(1) # 4
print m.end(1) # 10
print m.span(1) #(4,10)
十一、套接字:Socket
套接字主要是两个程序之间的“信息通道”。程序可能(通过网络连接)分布在不同的计算机上,通过套接字相互发送信息。
套接字包括两个:服务器套接字和客户机套接字。创建一个服务器套接字后,让它等待连接。这样它就在某个网络地址处 (IP地址和一个端口号的组合)监听。
处理客户端套接字通常比处理服务器端套接字容易,因为服务器必须准备随时处理客户端的连接,同时还要处理多个连接,而客户机只是简单地连接,完成事务,断开连接。
一个套接字就是一个socket模块中的socket类的实例。它的实例化需要3个参数:
第1个参数是地址族(默认是socket.AF_!NET) ;
第2个参数是流(socket.SOCK_STREAM,默认值)或数据报 (socket. SOCK _DGRAI叶)套接字
第3个参数是使用的协议(默认是0,使用默认值即可)。
对于一个普通的套接字,不需要提供任何参数。
服务器端套接宇使用bind方法后,再调用listen方法去监听这个给定的地址。
客户端套接字使用connect方在去连接到服务器在connect方法中使用的地址与bind方法中的地址相同(在服务器端,能实现很多功能,比如使用函数socket.gethostname得到当前主机名)。在这种情况下,一个地址就是一个格式为(host, port)的元组,
listen方法只有一个参数,即服务器未处理的连接的长度(即允许排队等待的连接数目,这些连接在停止接收之前等待接收)。
服务器端套接字开始监听后,它就可以接受客户端的连接。这个步骤使用accept方法来完成。
这个方法会阻塞(等待)直到客户端连接,然后该方法就返回一个格式为(client, address) 的元组, client是一个客户端套接字, address是一个前面解释过的地址。
套接字有两个方法: send和recv (用于接收),用于传输数据。可以使用字符串参数调用send 以发送数据,用一个所需的(最大)字节数做参数调用recv来接收数据。如果不能确定使用哪个数字比较好,那么1024是个很好的选择。
# 一个小型服务器
class Service:
import socket
s = socket.socket()
host = socket.gethostname()
port = 1234
s.bind((host, port))
s.listen(5)
while True:
c, addr = s.accept()
print 'Got connection from ', addr
c.send('Thanks for your connecting!')
c.close()
class Client:
import socket
s = socket.socket()
host = socket.gethostname()
port = 1234
s.connect(host, port)
print s.recv(1024)