详解Python中的多线程编程

2014-04-08  来源:本站原创  分类:Python  人气:8 

这篇文章主要介绍了详解Python中的多线程编程,Python中的多线程一直是Python学习中的重点和难点,要反复巩固!需要的朋友可以参考下

一、简介

多线程编程技术可以实现代码并行性,优化处理能力,同时功能的更小划分可以使代码的可重用性更好。Python中threading和Queue模块可以用来实现多线程编程。
二、详解
1、线程和进程
进程(有时被称为重量级进程)是程序的一次执行。每个进程都有自己的地址空间、内存、数据栈以及其它记录其运行轨迹的辅助数据。操作系统管理在其上运行的所有进程,并为这些进程公平地分配时间。进程也可以通过fork和spawn操作来完成其它的任务,不过各个进程有自己的内存空间、数据栈等,所以只能使用进程间通讯(IPC),而不能直接共享信息。
线程(有时被称为轻量级进程)跟进程有些相似,不同的是所有的线程运行在同一个进程中,共享相同的运行环境。它们可以想像成是在主进程或“主线程”中并行运行的“迷你进程”。线程有开始、顺序执行和结束三部分,它有一个自己的指令指针,记录自己运行到什么地方。线程的运行可能被抢占(中断)或暂时的被挂起(也叫睡眠)让其它的线程运行,这叫做让步。一个进程中的各个线程之间共享同一片数据空间,所以线程之间可以比进程之间更方便地共享数据以及相互通讯。线程一般都是并发执行的,正是由于这种并行和数据共享的机制使得多个任务的合作变为可能。实际上,在单CPU的系统中,真正的并发是不可能的,每个线程会被安排成每次只运行一小会,然后就把CPU让出来,让其它的线程去运行。在进程的整个运行过程中,每个线程都只做自己的事,在需要的时候跟其它的线程共享运行的结果。多个线程共同访问同一片数据不是完全没有危险的,由于数据访问的顺序不一样,有可能导致数据结果的不一致的问题,这叫做竞态条件。而大多数线程库都带有一系列的同步原语,来控制线程的执行和数据的访问。
2、使用线程
(1)全局解释器锁(GIL)
Python代码的执行由Python虚拟机(也叫解释器主循环)来控制。Python在设计之初就考虑到要在主循环中,同时只有一个线程在执行。虽然 Python 解释器中可以“运行”多个线程,但在任意时刻只有一个线程在解释器中运行。
对Python虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁能保证同一时刻只有一个线程在运行。在多线程环境中,Python 虚拟机按以下方式执行:a、设置 GIL;b、切换到一个线程去运行;c、运行指定数量的字节码指令或者线程主动让出控制(可以调用 time.sleep(0));d、把线程设置为睡眠状态;e、解锁 GIL;d、再次重复以上所有步骤。
在调用外部代码(如 C/C++扩展函数)的时候,GIL将会被锁定,直到这个函数结束为止(由于在这期间没有Python的字节码被运行,所以不会做线程切换)编写扩展的程序员可以主动解锁GIL。
(2)退出线程
当一个线程结束计算,它就退出了。线程可以调用thread.exit()之类的退出函数,也可以使用Python退出进程的标准方法,如sys.exit()或抛出一个SystemExit异常等。不过,不可以直接“杀掉”("kill")一个线程。
不建议使用thread模块,很明显的一个原因是,当主线程退出的时候,所有其它线程没有被清除就退出了。另一个模块threading就能确保所有“重要的”子线程都退出后,进程才会结束。
(3)Python的线程模块
Python提供了几个用于多线程编程的模块,包括thread、threading和Queue等。thread和threading模块允许程序员创建和管理线程。thread模块提供了基本的线程和锁的支持,threading提供了更高级别、功能更强的线程管理的功能。Queue模块允许用户创建一个可以用于多个线程之间共享数据的队列数据结构。
避免使用thread模块,因为更高级别的threading模块更为先进,对线程的支持更为完善,而且使用thread模块里的属性有可能会与threading出现冲突;其次低级别的thread模块的同步原语很少(实际上只有一个),而threading模块则有很多;再者,thread模块中当主线程结束时,所有的线程都会被强制结束掉,没有警告也不会有正常的清除工作,至少threading模块能确保重要的子线程退出后进程才退出。
3、thread模块
thread模块除了产生线程外,thread模块也提供了基本的同步数据结构锁对象(lock object也叫原语锁、简单锁、互斥锁、互斥量、二值信号量)。同步原语与线程的管理是密不可分的。
常用的线程函数以及LockType类型的锁对象的方法:

详解Python中的多线程编程

  #!/usr/bin/env python 

  import thread
  from time import sleep, ctime 

  def loop0():
    print '+++start loop 0 at:', ctime()
    sleep(4)
    print '+++loop 0 done at:', ctime() 

  def loop1():
    print '***start loop 1 at:', ctime()
    sleep(2)
    print '***loop 1 done at:', ctime() 

  def main():
    print '------starting at:', ctime()
    thread.start_new_thread(loop0, ())
    thread.start_new_thread(loop1, ())
    sleep(6)
    print '------all DONE at:', ctime() 

  if __name__ == '__main__':
    main() 

thread 模块提供的简单的多线程的机制,两个循环并发地被执行,总的运行时间为最慢的那个线程的运行时间(主线程6s),而不是所有的线程的运行时间之和。start_new_thread()要求要有前两个参数,就算想要运行的函数不要参数,也要传一个空的元组。

详解Python中的多线程编程

sleep(6)是让主线程停下来,主线程一旦运行结束,就关闭运行着其他两个线程。但这可能造成主线程过早或过晚退出,那就要使用线程锁,可以在两个子线程都退出后,主线程立即退出。
在CODE上查看代码片派生到我的代码片

  #!/usr/bin/env python 

  import thread
  from time import sleep, ctime 

  loops = [4, 2] 

  def loop(nloop, nsec, lock):
    print '+++start loop:', nloop, 'at:', ctime()
    sleep(nsec)
    print '+++loop:', nloop, 'done at:', ctime()
    lock.release() 

  def main():
    print '---starting threads...'
    locks = []
    nloops = range(len(loops)) 

    for i in nloops:
      lock = thread.allocate_lock()
      lock.acquire()
      locks.append(lock) 

    for i in nloops:
      thread.start_new_thread(loop,
        (i, loops[i], locks[i])) 

    for i in nloops:
      while locks[i].locked(): pass 

    print '---all DONE at:', ctime() 

  if __name__ == '__main__':
    main() 

详解Python中的多线程编程

4、threading模块
更高级别的threading模块,它不仅提供了Thread类,还提供了各种非常好用的同步机制。threading 模块里所有的对象:

详解Python中的多线程编程

thread模块不支持守护线程,当主线程退出时,所有的子线程不论它们是否还在工作,都会被强行退出。而threading模块支持守护线程,守护线程一般是一个等待客户请求的服务器,如果没有客户提出请求它就在那等着,如果设定一个线程为守护线程,就表示这个线程是不重要的,在进程退出的时候,不用等待这个线程退出。如果主线程退出不用等待那些子线程完成,那就设定这些线程的daemon属性,即在线程thread.start()开始前,调用setDaemon()函数设定线程的daemon标志(thread.setDaemon(True))就表示这个线程“不重要”。如果想要等待子线程完成再退出,那就什么都不用做或者显式地调用thread.setDaemon(False)以保证其daemon标志为False,可以调用thread.isDaemon()函数来判断其daemon标志的值。新的子线程会继承其父线程的daemon标志,整个Python会在所有的非守护线程退出后才会结束,即进程中没有非守护线程存在的时候才结束。
(1)threading的Thread类
它有很多thread模块里没有的函数,Thread对象的函数:

详解Python中的多线程编程

创建一个Thread的实例,传给它一个函数
在CODE上查看代码片派生到我的代码片

  #!/usr/bin/env python 

  import threading
  from time import sleep, ctime 

  loops = [ 4, 2 ] 

  def loop(nloop, nsec):
    print '+++start loop:', nloop, 'at:', ctime()
    sleep(nsec)
    print '+++loop:', nloop, 'done at:', ctime() 

  def main():
    print '---starting at:', ctime()
    threads = []
    nloops = range(len(loops)) 

    for i in nloops:
      t = threading.Thread(target=loop,
      args=(i, loops[i]))
      threads.append(t) 

    for i in nloops:      # start threads
      threads[i].start() 

    for i in nloops:      # wait for all
      threads[i].join()    # threads to finish 

    print '---all DONE at:', ctime() 

  if __name__ == '__main__':
    main() 

实例化一个Thread(调用 Thread())与调用thread.start_new_thread()之间最大的区别就是,新的线程不会立即开始。在创建线程对象,但不想马上开始运行线程的时候,这是一个很有用的同步特性。所有的线程都创建了之后,再一起调用 start()函数启动,而不是创建一个启动一个。而且也不用再管理一堆锁(分配锁、获得锁、释放锁、检查锁的状态等),只要简单地对每个线程调用join()主线程等待子线程的结束即可。join()还可以设置timeout的参数,即主线程等到超时为止。
join()的另一个比较重要的方面是它可以完全不用调用,一旦线程启动后,就会一直运行,直到线程的函数结束,退出为止。如果主线程除了等线程结束外,还有其它的事情要做,那就不用调用 join(),只有在等待线程结束的时候才调用join()。
创建一个Thread的实例,传给它一个可调用的类对象
[html] view plaincopy在CODE上查看代码片派生到我的代码片

  #!/usr/bin/env python 

  import threading
  from time import sleep, ctime 

  loops = [ 4, 2 ] 

  class ThreadFunc(object): 

    def __init__(self, func, args, name=''):
      self.name = name
      self.func = func
      self.args = args 

    def __call__(self):
      apply(self.func, self.args) 

  def loop(nloop, nsec):
    print 'start loop', nloop, 'at:', ctime()
    sleep(nsec)
    print 'loop', nloop, 'done at:', ctime() 

  def main():
    print 'starting at:', ctime()
    threads = []
    nloops = range(len(loops)) 

    for i in nloops:  # create all threads
      t = threading.Thread(target=ThreadFunc(loop, (i, loops[i]), loop.__name__))
      threads.append(t) 

    for i in nloops:  # start all threads
      threads[i].start() 

    for i in nloops:  # wait for completion
      threads[i].join() 

    print 'all DONE at:', ctime() 

  if __name__ == '__main__':
    main() 

与传一个函数很相似的另一个方法是在创建线程的时候,传一个可调用的类的实例供线程启动的时候执行,这是多线程编程的一个更为面向对象的方法。相对于一个或几个函数来说,类对象里可以使用类的强大的功能。创建新线程的时候,Thread对象会调用ThreadFunc对象,这时会用到一个特殊函数__call__()。由于已经有了要用的参数,所以就不用再传到Thread()的构造函数中。由于有一个参数的元组,这时要使用apply()函数或使用self.res = self.func(*self.args)。
从Thread派生出一个子类,创建一个这个子类的实例
在CODE上查看代码片派生到我的代码片

  #!/usr/bin/env python 

  import threading
  from time import sleep, ctime 

  loops = [ 4, 2 ] 

  class MyThread(threading.Thread):
    def __init__(self, func, args, name=''):
      threading.Thread.__init__(self)
      self.name = name
      self.func = func
      self.args = args 

    def getResult(self):
      return self.res 

    def run(self):
      print 'starting', self.name, 'at:', ctime()
      self.res = apply(self.func, self.args)
      print self.name, 'finished at:', ctime() 

  def loop(nloop, nsec):
    print 'start loop', nloop, 'at:', ctime()
    sleep(nsec)
    print 'loop', nloop, 'done at:', ctime() 

  def main():
    print 'starting at:', ctime()
    threads = []
    nloops = range(len(loops)) 

    for i in nloops:
      t = MyThread(loop, (i, loops[i]),
      loop.__name__)
      threads.append(t) 

    for i in nloops:
      threads[i].start() 

    for i in nloops:
      threads[i].join() 

    print 'all DONE at:', ctime() 

  if __name__ == '__main__':
    main()

子类化Thread类,MyThread子类的构造函数一定要先调用基类的构造函数,特殊函数__call__()在子类中,名字要改为run()。在 MyThread类中,加入一些用于调试的输出信息,把代码保存到myThread模块中,并导入这个类。除使用apply()函数来运行这些函数之外,还可以把结果保存到实现的self.res属性中,并创建一个新的函数getResult()来得到结果。
(2)threading模块中的其它函数

详解Python中的多线程编程

5、Queue模块
常用的 Queue 模块的属性:

详解Python中的多线程编程

Queue模块可以用来进行线程间通讯,让各个线程之间共享数据。Queue解决生产者-消费者的问题,现在创建一个队列,让生产者线程把新生产的货物放进去供消费者线程使用。生产者生产货物所要花费的时间无法预先确定,消费者消耗生产者生产的货物的时间也是不确定的。
在CODE上查看代码片派生到我的代码片

  #!/usr/bin/env python 

  from random import randint
  from time import sleep
  from Queue import Queue
  from myThread import MyThread 

  def writeQ(queue):
    print '+++producing object for Q...',
    queue.put('xxx', 1)
    print "+++size now:", queue.qsize() 

  def readQ(queue):
    val = queue.get(1)
    print '---consumed object from Q... size now', \
      queue.qsize() 

  def writer(queue, loops):
    for i in range(loops):
      writeQ(queue)
      sleep(randint(1, 3)) 

  def reader(queue, loops):
    for i in range(loops):
      readQ(queue)
      sleep(randint(2, 5)) 

  funcs = [writer, reader]
  nfuncs = range(len(funcs)) 

  def main():
    nloops = randint(2, 5)
    q = Queue(32) 

    threads = []
    for i in nfuncs:
      t = MyThread(funcs[i], (q, nloops), \
        funcs[i].__name__)
      threads.append(t) 

    for i in nfuncs:
      threads[i].start() 

    for i in nfuncs:
      threads[i].join() 

    print '***all DONE' 

  if __name__ == '__main__':
    main()

详解Python中的多线程编程

这个实现中使用了Queue对象和随机地生产(和消耗)货物的方式。生产者和消费者相互独立并且并发地运行,它们不一定是轮流执行的(随机数模拟)。writeQ()和readQ()函数分别用来把对象放入队列和消耗队列中的一个对象,在这里使用字符串'xxx'来表示队列中的对象。writer()函数就是一次往队列中放入一个对象,等待一会然后再做同样的事,一共做指定的次数,这个次数是由脚本运行时随机生成的。reader()函数做的事比较类似,只是它是用来消耗对象的。
6、线程相关模块
多线程相关的标准库模块:

详解Python中的多线程编程

三、总结
(1)一个要完成多项任务的程序,可以考虑每个任务使用一个线程,这样的程序在设计上相对于单线程做所有事的程序来说,更为清晰明了。
(2)单线程的程序在程序性能上的限制,尤其在有相互独立、运行时间不确定、多个任务的程序里,而把多个任务分隔成多个线程同时运行会比顺序运行速度更快。由于Python解释器是单线程的,所以不是所有的程序都能从多线程中得到好处。
(3)若有不足,请留言,在此先感谢!

相关文章
  • 详解Python中的多线程编程 2014-04-08

    这篇文章主要介绍了详解Python中的多线程编程,Python中的多线程一直是Python学习中的重点和难点,要反复巩固!需要的朋友可以参考下 一.简介 多线程编程技术可以实现代码并行性,优化处理能力,同时功能的更小划分可以使代码的可重用性更好.Python中threading和Queue模块可以用来实现多线程编程. 二.详解 1.线程和进程 进程(有时被称为重量级进程)是程序的一次执行.每个进程都有自己的地址空间.内存.数据栈以及其它记录其运行轨迹的辅助数据.操作系统管理在其上运行的所有进程,

  • 详解Python中的循环语句的用法 2014-01-03

    这篇文章主要介绍了详解Python中的循环语句的用法,循环语句是学习各个编程语言的最基本的基础知识,需要的朋友可以参考下 一.简介 Python的条件和循环语句,决定了程序的控制流程,体现结构的多样性.须重要理解,if.while.for以及与它们相搭配的 else. elif.break.continue和pass语句. 二.详解 1.if语句 Python中的if子句由三部分组成:关键字本身.用于判断结果真假的条件表达式以及当表达式为真或者非零时执行的代码块.if 语句的语法如下: if e

  • 详解Python中DOM方法的动态性 2015-01-27

    这篇文章主要介绍了详解Python中DOM方法的动态性,xml.dom模块在Python的网络编程中相当有用,本文来自于IBM官网的开发者技术文档,需要的朋友可以参考下 文档对象模型 xml.dom 模块对于 Python 程序员来说,可能是使用 XML 文档时功能最强大的工具.不幸的是,XML-SIG 提供的文档目前来说还比较少.W3C 语言无关的 DOM 规范填补了这方面的部分空白.但 Python 程序员最好有一个特定于 Python 语言的 DOM 的快速入门指南.本文旨在提供这样一个指

  • 详解Python中列表和元祖的使用方法 2014-03-11

    这篇文章主要介绍了详解Python中列表和元祖的使用方法,代码基于Python2.x版本,元祖和列表是Python学习当中的基础知识,需要的朋友可以参考下 list Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时添加和删除其中的元素. 比如,列出班里所有同学的名字,就可以用一个list表示: >>> classmates = ['Michael', 'Bob', 'Tracy'] >>> classmates ['Michael',

  • 详解Python中内置的NotImplemented类型的用法 2014-03-12

    这篇文章主要介绍了详解Python中内置的NotImplemented类型的用法,包括对相关的__eq__()和__ne__()两个方法使用的讲解,需要的朋友可以参考下 它是什么? >>> type(NotImplemented) <type 'NotImplementedType'> NotImplemented 是Python在内置命名空间中的六个常数之一.其他有False.True.None.Ellipsis 和 __debug__.和 Ellipsis很像,NotIm

  • 详解Python中的join()函数的用法 2014-04-19

    这篇文章主要介绍了详解Python中的join()函数的用法,join()函数主要用来拼接字符串,是Python学习当中的基础知识,需要的朋友可以参考下 函数:string.join() Python中有join()和os.path.join()两个函数,具体作用如下: join(): 连接字符串数组.将字符串.元组.列表中的元素以指定的字符(分隔符)连接生成一个新的字符串 os.path.join(): 将多个路径组合后返回 一.函数说明 1.join()函数 语法: 'sep'.join(s

  • 举例详解Python中的split()函数的使用方法 2014-04-27

    这篇文章主要介绍了举例详解Python中的split()函数的使用方法,split()函数的使用是Python学习当中的基础知识,通常用于将字符串切片并转换为列表,需要的朋友可以参考下 函数:split() Python中有split()和os.path.split()两个函数,具体作用如下: split():拆分字符串.通过指定分隔符对字符串进行切片,并返回分割后的字符串列表(list) os.path.split():按照路径将文件名和路径分割开 一.函数说明1.split()函数 语法:s

  • Python中尝试多线程编程的一个简明例子 2014-12-13

    这篇文章主要介绍了Python中尝试多线程编程的一个简明例子,由于GIL的存在,Python中的多线程编程一个是热点和难点问题,需要的朋友可以参考下 综述 多线程是程序设计中的一个重要方面,尤其是在服务器Deamon程序方面.无论何种系统,线程调度的开销都比传统的进程要快得多. Python可以方便地支持多线程.可以快速创建线程.互斥锁.信号量等等元素,支持线程读写同步互斥.美中不足的是,Python的运行在Python 虚拟机上,创建的多线程可能是虚拟的线程,需要由Python虚拟机来轮询调度

  • 详解Python中的正则表达式的用法 2015-02-04

    这篇文章主要介绍了详解Python中的正则表达式的用法,正则表达式在各个编程语言的学习当中都是基础知识,文中给出了Python2代码的示例,需要的朋友可以参考下 如果直接在命令行中利用input和raw_input读入一个文件来处理,并且想要采用直接将文件拖入命令行来处理的方式, input方法可以直接处理,而如果要采用raw_input的方法的话,读入文件地址会带有引号,还需要自己手动去掉引号才能处理文件. 在ipython中测试一下代码:(读入一个图片文件的地址字符串) a = input(

  • 用实例详解Python中的Django框架中prefetch_related()函数对数据库查询的优化 2015-02-10

    这篇文章主要介绍了用实例详解Python中的Django框架中prefetch_related()函数对数据库查询的优化,可减少对数据库的查询次数从而优化性能,需要的朋友可以参考下 实例的背景说明 假定一个个人信息系统,需要记录系统中各个人的故乡.居住地.以及到过的城市.数据库设计如下: Models.py 内容如下: from django.db import models class Province(models.Model): name = models.CharField(max_le

  • 详解Python中的装饰器.闭包和functools的教程 2015-04-28

    这篇文章主要介绍了详解Python中的装饰器.闭包和functools的教程,作者还给出了相关的Flask框架下的应用实例,需要的朋友可以参考下 装饰器(Decorators) 装饰器是这样一种设计模式:如果一个类希望添加其他类的一些功能,而不希望通过继承或是直接修改源代码实现,那么可以使用装饰器模式.简单来说Python中的装饰器就是指某些函数或其他可调用对象,以函数或类作为可选输入参数,然后返回函数或类的形式.通过这个在Python2.6版本中被新加入的特性可以用来实现装饰器设计模式. 顺便

  • 详解Python中的__init__和__new__ 2015-03-14

    这篇文章主要介绍了Python中的__init__和__new__的区别和实例详解它们的作用,需要的朋友可以参考下 一.__init__ 方法是什么? 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例的时候.例如: # -*- coding: utf-8 -*- class Person(object): """Silly Person""" def __ini

  • 详解Python中for循环的使用 2014-02-22

    这篇文章主要介绍了Python中for循环的使用,来自于IBM官方网站技术文档,需要的朋友可以参考下 for 循环 本系列前面 "探索 Python,第 5 部分:用 Python 编程" 一文讨论了 if 语句和 while 循环,讨论了复合语句以及适当缩进 Python 语句来指示相关 Python 代码块.该文的结尾介绍了 Python for 循环.但就其使用和功能来说,for 循环更值得关注,所以本文单独讲述该循环. for 循环有一个简单的语法,使您可以从容器对象中提取单个

  • 详解Python中的文本处理 2015-02-06

    这篇文章主要介绍了Python中的文本处理,包括从最基本的string模块的基础使用和更进一步的re模块的使用,本文来自IBM官方开发者技术文档,需要的朋友可以参考下 字符串 -- 不可改变的序列 如同大多数高级编程语言一样,变长字符串是 Python 中的基本类型.Python 在"后台"分配内存以保存字符串(或其它值),程序员不必为此操心.Python 还有一些其它高级语言没有的字符串处理功能. 在 Python 中,字符串是"不可改变的序列".尽管不能&quo

  • 详解Python中with语句的用法 2014-07-12

    这篇文章主要介绍了Python中with语句的用法,with语句的使用是Python学习过程当中的基础知识,本文来自于IBM官方技术文档,需要的朋友可以参考下 引言 with 语句是从 Python 2.5 开始引入的一种与异常处理相关的功能(2.5 版本中要通过 from __future__ import with_statement 导入后才可以使用),从 2.6 版本开始缺省可用(参考 What's new in Python 2.6? 中 with 语句相关部分介绍).with 语句适

  • 详解Python中的__new__()方法的使用 2014-10-05

    本文主要介绍了Python中的__new__()方法的使用的基本知识,本文中给出了基于Python2.x的代码实例,需要的朋友可以参考一下 先看下object类中对__new__()方法的定义: class object: @staticmethod # known case of __new__ def __new__(cls, *more): # known special case of object.__new__ """ T.__new__(S, ...) ->

  • 详解Python中__str__和__repr__方法的区别 2014-06-19

    这篇文章主要介绍了__str__和__repr__方法的区别 ,__str__和__repr__是基本的内置方法,使用时的区别也是Python学习当中的基础,需要的朋友可以参考下 对我当前工程进行全部测试需要花费不少时间.既然有 26 GB 空闲内存,为何不让其发挥余热呢? tmpfs 可以通过把文件系统保存在大内存中来加速测试的执行效率. 但优点也是缺点,tmpfs 只把结果保存在内存中,所以你必须自己编写脚本来把结果回写到磁盘上进行保留.而且这些脚本必须良好书写和执行,否则就要失去部分或全部

  • Python中的面向对象编程详解(上) 2014-04-17

    这篇文章主要介绍了Python中的面向对象编程详解(上),本文讲解了创建类.实例化类.类属性.特殊方法内建属性.静态变量属性.实例变量属性.方法属性.静态方法.类方法等内容,需要的朋友可以参考下 创建类 Python 类使用 class 关键字来创建.简单的类的声明可以是关键字后紧跟类名: class ClassName(bases): 'class documentation string' #'类文档字符串' class_suite #类体 实例化 通过类名后跟一对圆括号实例化一个类 复制代

  • Python中的面向对象编程详解(下) 2014-07-06

    这篇文章主要介绍了Python中的面向对象编程详解(下),本文讲解了继承.super关键字.重写.多重继承.类.实例和其他对象的内建函数.私有化等内容,需要的朋友可以参考下 继承 继承描述了基类的属性如何"遗传"给派生类.一个子类可以继承它的基类的任何属性,不管是数据属性还是方法. 创建子类的语法看起来与普通(新式)类没有区别,一个类名,后跟一个或多个需要从其中派生的父类: class SubClassName (ParentClass1[, ParentClass2, ...]):

  • Python中的并发编程 2013-10-01

    简介 我们将一个正在运行的程序称为进程.每个进程都有它自己的系统状态,包含内存状态.打开文件列表.追踪指令执行情况的程序指针以及一个保存局部变量的调用栈.通常情况下,一个进程依照一个单序列控制流顺序执行,这个控制流被称为该进程的主线程.在任何给定的时刻,一个程序只做一件事情. 一个程序可以通过Python库函数中的os或subprocess模块创建新进程(例如os.fork()或是subprocess.Popen()).然而,这些被称为子进程的进程却是独立运行的,它们有各自独立的系统状态以及主线