文件读写
可以使用open来操作文件,但是每次都要close1
2
3
4
5
6try:
f = open('iotest.txt', 'rb')
print f.read()
finally:
if f:
f.close()
所以推荐使用with ,能自动完成close1
2with open('iotest.txt', 'rb') as f:
print f.read().decode('gbk')
练习:遍历目录下所有文件,查找文件名包含test
的文件1
2
3
4
5
6
7
8
9
10
11
12
13absolute_path = sys.path[0]
#print absolute_path
def search(path,name):
for x in os.listdir(path):
fullname = os.path.join(path,x)
if os.path.isfile(fullname):
#print '文件:%s' % fullname
if name in x:
print '选中:%s' % fullname
else:
search(fullname,name)
search(absolute_path,'test')
序列化
我们把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思
序列化文件:1
2
3f = open('dump.txt', 'wb')
pickle.dump(dic, f)
f.close()
反序列化文件1
2
3f = open('dump.txt', 'rb')
d = pickle.load(f)
f.close()
字典序列化为json1
2
3str_json = json.dumps(dic)
print str_json
print json.loads(str_json)
对象序列化为json1
2
3
4
5
6
7
8
9
10class Student(object):
def __init__(self,name,age,score):
self.name = name
self.age = age
self.score = score
def student2dict(self,object):
return {'name':self.name,'age':self.age,'score':self.score}
hammer = Student('hammer',27,100)
print json.dumps(hammer,default=hammer.student2dict)
多进程
unix/lunix使用fork()
,会复制当前进程出一个子进程
子进程永远返回0,而父进程返回子进程的ID。这样做的理由是,一个父进程可以fork出很多子进程,所以,父进程要记下每个子进程的ID,而子进程只需要调用getppid()就可以拿到父进程的ID。
Python的os模块封装了常见的系统调用,其中就包括fork,可以在Python程序中轻松创建子进程:
Progress
使用Progress来写快平台多进程1
2
3
4
5
6
7
8
9
10
11
12# 1 使用Process来创建进程
def run_proc(name):
print 'Run child process %s (%s)...' % (name, os.getpid())
if __name__=='__main__':
print 'Parent process %s.' % os.getpid()
p = Process(target=run_proc, args=('test',))
print 'Process will start.'
p.start()
p.join()
print 'Process end.'
####################
Pool
使用Pool进程池,来批量创造进程1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#2 学习使用Pool,进程池
def long_time_task(name):
print '执行 tast %s(%s)...' % (name,os.getpid())
start = time.time()
time.sleep(random.random() * 3 )
end = time.time()
print 'Task %s run %0.2f seconds.' % (name,end - start)
if __name__ =='__main__':
print '父进程id %s .' % os.getpid()
p = Pool()
for i in range(5):
p.apply_async(long_time_task,args=(i,))
print '等待所有子进程执行完毕.'
p.close() #close之后Pool不能新增子进程了
p.join() # join方法会等待所有子进程执行完毕
print 'All done .'
#########################
进程间通信1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27# 3 学习使用Queue,实现进程间通信
# 写数据进程执行的代码:
def write(q):
for value in ['A', 'B', 'C']:
print 'Put %s to queue...' % value
q.put(value)
time.sleep(random.random())
# 读数据进程执行的代码:
def read(q):
while True:
value = q.get(True)
print 'Get %s from queue.' % value
if __name__=='__main__':
# 父进程创建Queue,并传给各个子进程:
q = Queue()
pw = Process(target=write, args=(q,))
pr = Process(target=read, args=(q,))
# 启动子进程pw,写入:
pw.start()
# 启动子进程pr,读取:
pr.start()
# 等待pw结束:
pw.join()
# pr进程里是死循环,无法等待其结束,只能强行终止:
pr.terminate()
多线程
Python是真正的多线程。
Python的标准库提供了两个模块:thread
和threading
,thread
是低级模块,threading
是高级模块,对thread
进行了封装。绝大多数情况下,我们只需要使用threading
这个高级模块。
Python解释器由于设计时有GIL全局锁,导致了多线程无法利用多核。多线程的并发在Python中就是一个美丽的梦。
意思是Python虽然是实际设计的多线程,但是由于全局所的存在,无法使用CPU的多核性能
1 | # 学习使用多线程,主要是threading |
选择进程还是线程
如果用多进程实现Master-Worker,主进程就是Master,其他进程就是Worker。
如果用多线程实现Master-Worker,主线程就是Master,其他线程就是Worker。
- cpu密集型:典型的是计算圆周率,视频解码
- io密集型:典型的是web服务器
如果充分利用操作系统提供的异步IO支持,就可以用单进程单线程模型来执行多任务,这种全新的模型称为事件驱动模型,Nginx就是支持异步IO的Web服务器。它在单核CPU上采用单进程模型就可以高效地支持多任务。在多核CPU上,可以运行多个进程(数量与CPU核心数相同)。
python单进程的异步编程模型称为协程,有了协程的支持,就可以基于事件驱动编写高效的多任务程序.
类似于nodejs服务器,也是采用的基于事件驱动的单进程单线程来执行多任务。
分布式进程
为什么选用Process,而不是Thread呢,因为进程可以部署到不同的机器上,形成分布式进程。
比如:
机器1》 创建Queue,把Queue注册到网络上暴露,供其他进程访问