python实现时间序列中如何实现多个%s时列表展开

没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!python中实现定制类的特殊方法总结
转载 &更新时间:日 09:44:47 & 作者:wuhn
这篇文章主要介绍了python中实现定制类的特殊方法总结,本文讲解了__str__、__iter__、__getitem__、__getattr__、__call__等特殊方法,需要的朋友可以参考下
看到类似__slots__这种形如__xxx__的变量或者函数名就要注意,这些在Python中是有特殊用途的。
__slots__我们已经知道怎么用了,__len__()方法我们也知道是为了能让class作用于len()函数。
除此之外,Python的class中还有许多这样有特殊用途的函数,可以帮助我们定制类。
我们先定义一个Student类,打印一个实例:
&&& class Student(object):
...&&&& def __init__(self, name):
...&&&&&&&& self.name = name
&&& print Student('Michael')
&__main__.Student object at 0x109afb190&
打印出一堆&__main__.Student object at 0x109afb190&,不好看。
怎么才能打印得好看呢?只需要定义好__str__()方法,返回一个好看的字符串就可以了:
&&& class Student(object):
...&&&& def __init__(self, name):
...&&&&&&&& self.name = name
...&&&& def __str__(self):
...&&&&&&&& return 'Student object (name: %s)' % self.name
&&& print Student('Michael')
Student object (name: Michael)
这样打印出来的实例,不但好看,而且容易看出实例内部重要的数据。
但是细心的朋友会发现直接敲变量不用print,打印出来的实例还是不好看:
&&& s = Student('Michael')
&__main__.Student object at 0x109afb310&
这是因为直接显示变量调用的不是__str__(),而是__repr__(),两者的区别是__str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串,也就是说,__repr__()是为调试服务的。
解决办法是再定义一个__repr__()。但是通常__str__()和__repr__()代码都是一样的,所以,有个偷懒的写法:
class Student(object):
&&& def __init__(self, name):
&&&&&&& self.name = name
&&& def __str__(self):
&&&&&&& return 'Student object (name=%s)' % self.name
&&& __repr__ = __str__
如果一个类想被用于for ... in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的next()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。
我们以斐波那契数列为例,写一个Fib类,可以作用于for循环:
class Fib(object):
&&& def __init__(self):
&&&&&&& self.a, self.b = 0, 1 # 初始化两个计数器a,b
&&& def __iter__(self):
&&&&&&& return self # 实例本身就是迭代对象,故返回自己
&&& def next(self):
&&&&&&& self.a, self.b = self.b, self.a + self.b # 计算下一个值
&&&&&&& if self.a & 100000: # 退出循环的条件
&&&&&&&&&&& raise StopIteration();
&&&&&&& return self.a # 返回下一个值
现在,试试把Fib实例作用于for循环:
&&& for n in Fib():
...&&&& print n
__getitem__
Fib实例虽然能作用于for循环,看起来和list有点像,但是,把它当成list来使用还是不行,比如,取第5个元素:
&&& Fib()[5]
Traceback (most recent call last):
& File "&stdin&", line 1, in &module&
TypeError: 'Fib' object does not support indexing
要表现得像list那样按照下标取出元素,需要实现__getitem__()方法:
class Fib(object):
&&& def __getitem__(self, n):
&&&&&&& a, b = 1, 1
&&&&&&& for x in range(n):
&&&&&&&&&&& a, b = b, a + b
&&&&&&& return a
现在,就可以按下标访问数列的任意一项了:
&&& f = Fib()
&&& f[100]
但是list有个神奇的切片方法:
&&& range(100)[5:10]
[5, 6, 7, 8, 9]
对于Fib却报错。原因是__getitem__()传入的参数可能是一个int,也可能是一个切片对象slice,所以要做判断:
class Fib(object):
&&& def __getitem__(self, n):
&&&&&&& if isinstance(n, int):
&&&&&&&&&&& a, b = 1, 1
&&&&&&&&&&& for x in range(n):
&&&&&&&&&&&&&&& a, b = b, a + b
&&&&&&&&&&& return a
&&&&&&& if isinstance(n, slice):
&&&&&&&&&&& start = n.start
&&&&&&&&&&& stop = n.stop
&&&&&&&&&&& a, b = 1, 1
&&&&&&&&&&& L = []
&&&&&&&&&&& for x in range(stop):
&&&&&&&&&&&&&&& if x &= start:
&&&&&&&&&&&&&&&&&&& L.append(a)
&&&&&&&&&&&&&&& a, b = b, a + b
&&&&&&&&&&& return L
现在试试Fib的切片:
&&& f = Fib()
&&& f[0:5]
[1, 1, 2, 3, 5]
&&& f[:10]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
但是没有对step参数作处理:
&&& f[:10:2]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
也没有对负数作处理,所以,要正确实现一个__getitem__()还是有很多工作要做的。
此外,如果把对象看成dict,__getitem__()的参数也可能是一个可以作key的object,例如str。
与之对应的是__setitem__()方法,把对象视作list或dict来对集合赋值。最后,还有一个__delitem__()方法,用于删除某个元素。
总之,通过上面的方法,我们自己定义的类表现得和Python自带的list、tuple、dict没什么区别,这完全归功于动态语言的“鸭子类型”,不需要强制继承某个接口。
__getattr__
正常情况下,当我们调用类的方法或属性时,如果不存在,就会报错。比如定义Student类:
class Student(object):
&&& def __init__(self):
&&&&&&& self.name = 'Michael'
调用name属性,没问题,但是,调用不存在的score属性,就有问题了:
&&& s = Student()
&&& print s.name
&&& print s.score
Traceback (most recent call last):
AttributeError: 'Student' object has no attribute 'score'
错误信息很清楚地告诉我们,没有找到score这个attribute。
要避免这个错误,除了可以加上一个score属性外,Python还有另一个机制,那就是写一个__getattr__()方法,动态返回一个属性。修改如下:
class Student(object):
&&& def __init__(self):
&&&&&&& self.name = 'Michael'
&&& def __getattr__(self, attr):
&&&&&&& if attr=='score':
&&&&&&&&&&& return 99
当调用不存在的属性时,比如score,Python解释器会试图调用__getattr__(self, 'score')来尝试获得属性,这样,我们就有机会返回score的值:
&&& s = Student()
&&& s.name
&&& s.score
返回函数也是完全可以的:
class Student(object):
&&& def __getattr__(self, attr):
&&&&&&& if attr=='age':
&&&&&&&&&&& return lambda: 25
只是调用方式要变为:
&&& s.age()
注意,只有在没有找到属性的情况下,才调用__getattr__,已有的属性,比如name,不会在__getattr__中查找。
此外,注意到任意调用如s.abc都会返回None,这是因为我们定义的__getattr__默认返回就是None。要让class只响应特定的几个属性,我们就要按照约定,抛出AttributeError的错误:
class Student(object):
&&& def __getattr__(self, attr):
&&&&&&& if attr=='age':
&&&&&&&&&&& return lambda: 25
&&&&&&& raise AttributeError('\'Student\' object has no attribute \'%s\'' % attr)
这实际上可以把一个类的所有属性和方法调用全部动态化处理了,不需要任何特殊手段。
这种完全动态调用的特性有什么实际作用呢?作用就是,可以针对完全动态的情况作调用。
举个例子:
现在很多网站都搞REST API,比如新浪微博、豆瓣啥的,调用API的URL类似:
如果要写SDK,给每个URL对应的API都写一个方法,那得累死,而且,API一旦改动,SDK也要改。
利用完全动态的__getattr__,我们可以写出一个链式调用:
class Chain(object):
&&& def __init__(self, path=''):
&&&&&&& self._path = path
&&& def __getattr__(self, path):
&&&&&&& return Chain('%s/%s' % (self._path, path))
&&& def __str__(self):
&&&&&&& return self._path
&&& Chain().status.user.timeline.list
'/status/user/timeline/list'
这样,无论API怎么变,SDK都可以根据URL实现完全动态的调用,而且,不随API的增加而改变!
还有些REST API会把参数放到URL中,比如GitHub的API:
GET /users/:user/repos
调用时,需要把:user替换为实际用户名。如果我们能写出这样的链式调用:
Chain().users('michael').repos
就可以非常方便地调用API了。有兴趣的童鞋可以试试写出来。
一个对象实例可以有自己的属性和方法,当我们调用实例方法时,我们用instance.method()来调用。能不能直接在实例本身上调用呢?类似instance()?在Python中,答案是肯定的。
任何类,只需要定义一个__call__()方法,就可以直接对实例进行调用。请看示例:
class Student(object):
&&& def __init__(self, name):
&&&&&&& self.name = name
&&& def __call__(self):序. multiprocessingpython中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。Python提供了非常好用的多进程包multiprocessing,只需要定义一个函数,Python会完成其他所有事情。借助这个包,可以轻松完成从单进程到并发执行的转换。multiprocessing支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。
1. Process
创建进程的类:Process([group [, target [, name [, args [, kwargs]]]]]),target表示调用对象,args表示调用对象的位置参数元组。kwargs表示调用对象的字典。name为别名。group实质上不使用。方法:is_alive() 、join([timeout])、run()、start()、terminate()。其中,Process以start()启动某个进程。
is_alive():判断该进程是否还活着
join([timeout]):主进程阻塞,等待子进程的退出, join方法要在close或terminate之后使用。
run():进程p调用start()时,自动调用run()
属性:authkey、daemon(要通过start()设置)、exitcode(进程在运行时为None、如果为&N,表示被信号N结束)、name、pid。其中daemon是父进程终止后自动终止,且自己不能产生新进程,必须在start()之前设置。
例1.1:创建函数并将其作为单个进程
import multiprocessing
import time
def worker(interval):
while n & 0:
print("The time is {0}".format(time.ctime()))
#输出时间的格式
time.sleep(interval)
if __name__ == "__main__":
p = multiprocessing.Process(target = worker, args = (3,))
print "p.pid:", p.pid
print "p.name:", p.name
print "p.is_alive:", p.is_alive()
p.pid:&8736
p.name: Process-1
p.is_alive: True
The time is Tue Apr&21&20:55:12&2015
The time is Tue Apr&21&20:55:15&2015
The time is Tue Apr&21&20:55:18&2015
The time is Tue Apr&21&20:55:21&2015
The time is Tue Apr&21&20:55:24&2015
例1.2:创建函数并将其作为多个进程
import multiprocessing
import time
def worker_1(interval):
print "worker_1"
time.sleep(interval)
print "end worker_1"
def worker_2(interval):
print "worker_2"
time.sleep(interval)
print "end worker_2"
def worker_3(interval):
print "worker_3"
time.sleep(interval)
print "end worker_3"
if __name__ == "__main__":
  p1 = Process(target=worker_1, args=(6,))
p2 = Process(target=worker_2, args=(4,))
p3 = Process(target=worker_3, args=(2,))
  p1.start() p2.start() p3.start()
  print("The number of CPU is:" + str(cpu_count()))
   for p in active_children():
   print("child p.name:=%s" % p.name + "\tp.id=%s" % str(p.pid))
  print(p1.pid)
  print("END-----")
The number of CPU is:4child p.name:=Process-2 p.id=3864child p.name:=Process-3 p.id=3256child p.name:=Process-1 p.id=73367336END-----worker_1worker_2worker_3end worker_3end worker_2end worker_1
例1.3:将进程定义为类
import multiprocessing
import time
class ClockProcess(multiprocessing.Process):
def __init__(self, interval):
multiprocessing.Process.__init__(self)
self.interval = interval
def run(self):
while n & 0:
print("the time is {0}".format(time.ctime()))
time.sleep(self.interval)
if __name__ == '__main__':
p = ClockProcess(3)
注:进程p调用start()时,自动调用run()
the time is Tue Apr&21&20:31:30&2015
the time is Tue Apr&21&20:31:33&2015
the time is Tue Apr&21&20:31:36&2015
the time is Tue Apr&21&20:31:39&2015
the time is Tue Apr&21&20:31:42&2015
例1.4:daemon程序对比结果
#1.4-1&不加daemon属性
import multiprocessing
import time
def worker(interval):
print("work start:{0}".format(time.ctime()));
time.sleep(interval)
print("work end:{0}".format(time.ctime()));
if __name__ == "__main__":
p = multiprocessing.Process(target = worker, args = (3,))
print "end!"
work start:Tue Apr&21&21:29:10&2015
work end:Tue Apr&21&21:29:13&2015
#1.4-2&加上daemon属性
import multiprocessing
import time
def worker(interval):
print("work start:{0}".format(time.ctime()));
time.sleep(interval)
print("work end:{0}".format(time.ctime()));
if __name__ == "__main__":
p = multiprocessing.Process(target = worker, args = (3,))
p.daemon = True
print "end!"
注:因子进程设置了daemon属性,主进程结束,它们就随着结束了。
  在多线程模型中,默认情况下(sub-Thread.daemon=False)主线程会等待子线程退出后再退出,而如果sub- Thread.setDaemon(True)时,主线程不会等待子线程,直接退出,而此时子线程会随着主线程的对出而退出,避免这种情况,主线程中需要 对子线程进行join,等待子线程执行完毕后再退出。对应的,在多进程模型中,Process类也有daemon属性,而它表示的含义与 Thread.daemon类似,当设置sub-Process.daemon=True时,主进程中需要对子进程进行等待,否则子进程会随着主进程的退 出而退出
#1.4-3&设置daemon执行完结束的方法
import multiprocessing
import time
def worker(interval):
print("work start:{0}".format(time.ctime()));
time.sleep(interval)
print("work end:{0}".format(time.ctime()));
if __name__ == "__main__":
p = multiprocessing.Process(target = worker, args = (3,))
p.daemon = True
print "end!"
work start:Tue Apr&21&22:16:32&2015
work end:Tue Apr&21&22:16:35&2015
当多个进程需要访问共享资源的时候,Lock可以用来避免访问的冲突。
import multiprocessing
import sys
def worker_with(lock, f):
with lock:
fs = open(f, 'a+')
while n & 1:
fs.write("Lockd acquired via with\n")
fs.close()
def worker_no_with(lock, f):
lock.acquire()
fs = open(f, 'a+')
while n & 1:
fs.write("Lock acquired directly\n")
fs.close()
lock.release()
if __name__ == "__main__":
lock = multiprocessing.Lock()
f = "file.txt"
w = multiprocessing.Process(target = worker_with, args=(lock, f))
nw = multiprocessing.Process(target = worker_no_with, args=(lock, f))
nw.start()
print "end"
结果(输出文件)
Lockd acquired via with
Lockd acquired via with
Lockd acquired via with
Lockd acquired via with
Lockd acquired via with
Lockd acquired via with
Lockd acquired via with
Lockd acquired via with
Lockd acquired via with
Lock acquired directly
Lock acquired directly
Lock acquired directly
Lock acquired directly
Lock acquired directly
Lock acquired directly
Lock acquired directly
Lock acquired directly
Lock acquired directly
3. Semaphore
Semaphore用来控制对共享资源的访问数量,例如池的最大连接数。
import multiprocessing
import time
def worker(s, i):
s.acquire()
print(multiprocessing.current_process().name + "acquire");
time.sleep(i)
print(multiprocessing.current_process().name + "release\n");
s.release()
if __name__ == "__main__":
s = multiprocessing.Semaphore(2)
for i in range(5):
p = multiprocessing.Process(target = worker, args=(s, i*2))
Process-1acquire
Process-1release
Process-2acquire
Process-3acquire
Process-2release
Process-5acquire
Process-3release
Process-4acquire
Process-5release
Process-4release
import multiprocessing
import time
def worker(s, ):
s.acquire()
print(multiprocessing.current_process().name + "acquire")
time.sleep(1)
# print(multiprocessing.current_process().name + "release\n")
s.release()
if __name__ == "__main__":
s = multiprocessing.Semaphore(2)
for i in range(5):
p = multiprocessing.Process(target = worker, args=(s, ))
# time.sleep(0.01)
p.start()#####结果######
Process-4acquireProcess-3acquire
Process-1acquireProcess-2acquire
Process-5acquire
Event用来实现进程间同步通信。
import multiprocessingimport timedef wait_for_event(e):
print("wait_for_event: starting")
e.wait() #一直阻塞的去等待set值
print('*****')
print("wairt_for_event: e.is_set()-&" + str(e.is_set()))def wait_for_event_timeout(e, t):
print("wait_for_event_timeout:starting")
#等2s去取set值
print('------')
print("wait_for_event_timeout:e.is_set-&" + str(e.is_set()))if __name__ == "__main__":
e = multiprocessing.Event()
w1 = multiprocessing.Process(name="block", target=wait_for_event, args=(e,))
w2 = multiprocessing.Process(name="non-block", target=wait_for_event_timeout, args=(e, 2))
w1.start()
w2.start()
time.sleep(10)
# 设置set的值
print("main: event is set")
wait_for_event: startingwait_for_event_timeout:starting------wait_for_event_timeout:e.is_set-&Falsemain: event is set*****wairt_for_event: e.is_set()-&True
Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递。put方法用以插入数据到队列中,put方法还有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,该方法会阻塞timeout指定的时间,直到该队列有剩余的空间。如果超时,会抛出Queue.Full异常。如果blocked为False,但该Queue已满,会立即抛出Queue.Full异常。
get方法可以从队列读取并且删除一个元素。同样,get方法有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,那么在等待时间内没有取到任何元素,会抛出Queue.Empty异常。如果blocked为False,有两种情况存在,如果Queue有一个值可用,则立即返回该值,否则,如果队列为空,则立即抛出Queue.Empty异常。Queue的一段示例代码:
import multiprocessing
def writer_proc(q):
q.put(1, block = False)
def reader_proc(q):
print q.get(block = False)
if __name__ == "__main__":
q = multiprocessing.Queue()
writer = multiprocessing.Process(target=writer_proc, args=(q,))
writer.start()
reader = multiprocessing.Process(target=reader_proc, args=(q,))
reader.start()
#reader.join()
这样会一直阻塞
#writer.join()
Pipe方法返回(conn1, conn2)代表一个管道的两个端。Pipe方法有duplex参数,如果duplex参数为True(默认值),那么这个管道是全双工模式,也就是说conn1和conn2均可收发。duplex为False,conn1只负责接受消息,conn2只负责发送消息。
send和recv方法分别是发送和接受消息的方法。例如,在全双工模式下,可以调用conn1.send发送消息,conn1.recv接收消息。如果没有消息可接收,recv方法会一直阻塞。如果管道已经被关闭,那么recv方法会抛出EOFError。
import multiprocessingimport timedef proc1(pipe):
# while True:
for i in range(3):
print("send: %s" %(i))
pipe.send(i)
time.sleep(1)def proc2(pipe):
while True:
print ("proc2 rev:", pipe.recv())
time.sleep(1)def proc3(pipe):
while True:
print("PROC3 rev:", pipe.recv())
time.sleep(1)if __name__ == "__main__":
pipe = multiprocessing.Pipe()
p1 = multiprocessing.Process(target=proc1, args=(pipe[0],))
p2 = multiprocessing.Process(target=proc2, args=(pipe[1],))
#p3 = multiprocessing.Process(target=proc3, args=(pipe[1],))
p1.start()
p2.start()
# p3.start()
# p1.join()
# p2.join()
# p3.join()#######结果########
send: 0proc2 rev: 0send: 1proc2 rev: 1send: 2proc2 rev: 2
在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间。当被操作对象数目不大时,可以直接利用multiprocessing中的Process动态成生多个进程,十几个还好,但如果是上百个,上千个目标,手动的去限制进程数量却又太过繁琐,此时可以发挥进程池的功效。Pool可以提供指定数量的进程,供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来它。
import multiprocessing
import time
def func(msg, a):
# if a == 1:
time.sleep(8)
print("msg:", msg)
print("++++")
time.sleep(3)
# print("end")
if __name__ == "__main__":
pool = multiprocessing.Pool(processes=3)
for i in range(7):
msg = "hello %d" % (i)
# 维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去
pool.apply_async(func, (msg, a, ))
pool.close()
# 调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束
pool.join()
print("Sub-process(es) done.")
例7.1:使用进程池(非阻塞)
#coding: utf-8
import multiprocessing
import time
def func(msg):
print "msg:", msg
time.sleep(3)
print "end"
if __name__ == "__main__":
pool = multiprocessing.Pool(processes = 3)
for i in xrange(4):
msg = "hello %d" %(i)
pool.apply_async(func, (msg, ))
#维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去
print "Mark~ Mark~ Mark~~~~~~~~~~~~~~~~~~~~~~"
pool.close()
pool.join()
#调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束
print "Sub-process(es) done."
一次执行结果
mMsg: hark~ Mark~ Mark~~~~~~~~~~~~~~~~~~~~~~ello&0
msg: hello&1
msg: hello&2
msg: hello&3
Sub-process(es) done.
函数解释:
apply_async(func[, args[, kwds[, callback]]]) 它是非阻塞,apply(func[, args[, kwds]])是阻塞的(理解区别,看例1例2结果区别)
close() & &关闭pool,使其不在接受新的任务。
terminate() & &结束工作进程,不在处理未完成的任务。
join() & &主进程阻塞,等待子进程的退出, join方法要在close或terminate之后使用。
执行说明:创建一个进程池pool,并设定进程的数量为3,xrange(4)会相继产生四个对象[0, 1, 2, 4],四个对象被提交到pool中,因pool指定进程数为3,所以0、1、2会直接送到进程中执行,当其中一个执行完事后才空出一个进程处理对象3,所以会出现输出&msg: hello 3&出现在"end"后。因为为非阻塞,主函数会自己执行自个的,不搭理进程的执行,所以运行完for循环后直接输出&mMsg: hark~ Mark~ Mark~~~~~~~~~~~~~~~~~~~~~~&,主程序在pool.join()处等待各个进程的结束。
例7.2:使用进程池(阻塞)
#coding: utf-8
import multiprocessing
import time
def func(msg):
print "msg:", msg
time.sleep(3)
print "end"
if __name__ == "__main__":
pool = multiprocessing.Pool(processes = 3)
for i in xrange(4):
msg = "hello %d" %(i)
pool.apply(func, (msg, ))
#维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去
print "Mark~ Mark~ Mark~~~~~~~~~~~~~~~~~~~~~~"
pool.close()
pool.join()
#调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束
print "Sub-process(es) done."
一次执行的结果
msg: hello&0
msg: hello&1
msg: hello&2
msg: hello&3
Mark~ Mark~ Mark~~~~~~~~~~~~~~~~~~~~~~
Sub-process(es) done.
例7.3:使用进程池,并关注结果
import multiprocessing
import time
def func(msg):
print "msg:", msg
time.sleep(3)
print "end"
return "done" + msg
if __name__ == "__main__":
pool = multiprocessing.Pool(processes=4)
result = []
for i in xrange(3):
msg = "hello %d" %(i)
result.append(pool.apply_async(func, (msg, )))
pool.close()
pool.join()
for res in result:
print ":::", res.get()
print "Sub-process(es) done."
一次执行结果
msg: hello&0
msg: hello&1
msg: hello&2
::: donehello&0
::: donehello&1
::: donehello&2
Sub-process(es) done.
例7.4:使用多个进程池
import multiprocessing
import os, time, random
def Lee(i):
print('1', i)
time.sleep(3)
print('-----')
# print("\nRun task Lee-%s" %(os.getpid())) #os.getpid()获取当前的进程的ID
# start = time.time()
# time.sleep(random.random() * 10) #random.random()随机生成0-1之间的小数
# end = time.time()
# print('Task Lee, runs %0.2f seconds.' % (end - start))
def Marlon(i):
print('2', i)
time.sleep(3)
print('-----')
# print("\nRun task Marlon-%s" % (os.getpid()))
# start = time.time()
# time.sleep(random.random() * 40)
# end = time.time()
# print('Task Marlon runs %0.2f seconds.' %(end - start))
def Allen(i):
print('3', i)
time.sleep(3)
print('-----')
# print("\nRun task Allen-%s" %(os.getpid()))
# start = time.time()
# time.sleep(random.random() * 30)
# end = time.time()
# print('Task Allen runs %0.2f seconds.' %(end - start))
def Frank(i):
print('4', i)
time.sleep(3)
print('-----')
# print("\nRun task Frank-%s" %(os.getpid()))
# start = time.time()
# time.sleep(random.random() * 20)
# end = time.time()
# print('Task Frank runs %0.2f seconds.' %(end - start))
if __name__ == '__main__':
function_list = [Lee, Marlon, Allen, Frank]
# print("parent process %s" % (os.getpid()))
pool = multiprocessing.Pool(4)
for func in function_list:
# Pool执行函数,apply执行函数,当有一个进程执行完毕后,会添加一个新的进程到pool中
for i in ['a', 'b', 'c','d', 'e', 'f', 'g']:
pool.apply_async(func, args=(i,))
print('Waiting for all subprocesses done...')
pool.close()
# 调用join之前,一定要先调用close() 函数,否则会出错, close()执行后不会有新的进程加入到pool,join函数等待素有子进程结束
pool.join()
print('All subprocesses done.')
#coding: utf-8
import multiprocessing
import os, time, random
def Lee():
print "\nRun task Lee-%s" %(os.getpid()) #os.getpid()获取当前的进程的ID
start = time.time()
time.sleep(random.random() * 10) #random.random()随机生成0-1之间的小数
end = time.time()
print 'Task Lee, runs %0.2f seconds.' %(end - start)
def Marlon():
print "\nRun task Marlon-%s" %(os.getpid())
start = time.time()
time.sleep(random.random() * 40)
end=time.time()
print 'Task Marlon runs %0.2f seconds.' %(end - start)
def Allen():
print "\nRun task Allen-%s" %(os.getpid())
start = time.time()
time.sleep(random.random() * 30)
end = time.time()
print 'Task Allen runs %0.2f seconds.' %(end - start)
def Frank():
print "\nRun task Frank-%s" %(os.getpid())
start = time.time()
time.sleep(random.random() * 20)
end = time.time()
print 'Task Frank runs %0.2f seconds.' %(end - start)
if __name__=='__main__':
function_list=
[Lee, Marlon, Allen, Frank]
print "parent process %s" %(os.getpid())
pool=multiprocessing.Pool(4)
for func in function_list:
pool.apply_async(func)
#Pool执行函数,apply执行函数,当有一个进程执行完毕后,会添加一个新的进程到pool中
print 'Waiting for all subprocesses done...'
pool.close()
pool.join()
#调用join之前,一定要先调用close() 函数,否则会出错, close()执行后不会有新的进程加入到pool,join函数等待素有子进程结束
print 'All subprocesses done.'
一次执行结果
parent process&7704
Waiting for&all&subprocesses done...
Run task Lee-6948
Run task Marlon-2896
Run task Allen-7304
Run task Frank-3052
Task Lee, runs&1.59&seconds.
Task Marlon runs&8.48&seconds.
Task Frank runs&15.68&seconds.
Task Allen runs&18.08&seconds.
All subprocesses done.
阅读(...) 评论()

我要回帖

更多关于 怎么学习python 的文章

 

随机推荐