Python中多线程的实现与类的简介

在介绍多线程之前,先来介绍下Python中的类。算是给像我这样,从java或c++转入python的小白一些“前车之鉴”。

python作为面向对象的语言,自然也会有类、属性、继承...这些概念。而基于以往的java经验,我打算自定义一个类来实现多线程。

好吧,开始写class MyThread:,然后定义属性,啥?要给成员变量赋值?这不是构造函数做的事吗??算了,先不管属性,写构造函数吧。class MyThread():...报错!这是什么情况??哦,要用 def __init__...嗯,总算定义好了一个类,来个实例试试, MyThread mt = ...又报错!哦,不能这样写啊?早说嘛!!!(注:该段是错误操作,纯属娱乐)

好了,废话写了一堆,下面直接上研究成果,真可谓“不懂真是难,懂了真简单”

一.类的定义及相关操作

# coding=UTF-8
'''python中类的简单介绍
'''

class human:  # 定义human类
    '''构造函数:
      self必须有,等价于'this'
      name、age为human的属性,即成员变量,前面加双下划线'__'表示为私有,不能被继承,赋值时:self.__xx=xx
    '''

    def __init__(self, name, age):
        self.name = name  # 为成员变量赋值
        self.age = age

    def speak(self):
        print '我会说话'

class man(human):  # 定义man类,继承human类。注:括号中为父类列表

    def __init__(self, name, age, sex):  # 重写父类构造方法,可增加自己的属性,如sex
        human.__init__(self, name, age)  # 调用父类的构造函数
        self.sex = sex

    def speak(self):  # 重写父类方法
        print '我是男人,我也会说话'

    def fun(self):  # 定义无参方法,self为必须有的,不算参数
        print '我是男人,我力气大'

    def sing(self, song):  # 定义有参方法
        print '我是男人,我会唱' + song

class woman(human):  # 定义woman类,继承human类

    def __init__(self, name, age, sex):
        human.__init__(self, name, age)
        self.sex = sex

    def speak(self):
        print '我是女人,我也会说话'

    def setName(self, name):  # 定义设置name属性的函数,即set方法
        self.name = name

    def getName(self):  # 定义获取name属性的函数,即get方法
        return self.name


def test(obj):   # 定义实现多态的函数,参数obj相当于 java中的 'human obj',即一个父类引用型变量
    print  # 换行
    print '名字:', obj.name
    print '年纪:', obj.age
    obj.speak()

# 测试
if __name__ == '__main__':
    h = human('人', '500万年')  # 创建human类对象
    m = man('小明', 18, '男')
    w = woman('小芳', 20, '女')
    # human类测试
    test(h)  # 传入不同的类对象

    # man类测试
    test(m)
    print '性别:', m.sex  # 打印男人的sex属性
    m.fun()  # 测试无参函数
    m.sing('情歌')  # 测试有参函数

    # woman类测试
    test(w)
    print '性别:', w.sex
    print '我原来的名字是:', w.getName()
    w.setName('小红')  # 更改name属性
    print '现在我的名字是:', w.getName()

运行结果:

Python中多线程的实现与类的简介_第1张图片

      现在总算对类有个简单的了解了,那下面来聊聊多线程吧。

      多线程,顾名思义,就是多个线程同时工作,如果将一个线程比作一个任务的话,那就是多个任务同时进行。比如我,现在就是边听歌,边写博客。而这,就是一个简单的多线程例子。

       定义暂时搞清楚了,但问题又来了,用多线程究竟有什么好处呢?俗话说,光说不练假把式!下面我们就来做个小实验,看看多线程的“好处”何在。

二.多线程的实现及与单线程的简单比较

     1.多线程的实现(这里介绍继承threading.Thread类的实现方法)  
# coding=utf-8
import threading
import time

class MyThread(threading.Thread):  # 定义线程类继承 threading.Thread

    def __init__(self, group, target, name, args):
        threading.Thread.__init__(self, group, target, name, args)
        '''重写父类的构造函数。
           group:线程组,未实现,但实例化时必须有这个参数,设为None
           target:指向线程要绑定的函数
           name:线程名
           args:绑定函数的所需参数,为元组类型
       '''

def listen(sname): #定义要绑定运行的函数
    for i in range(7):
        print threading.current_thread().getName(), '--我在听' + sname
        time.sleep(2)

def read(bname):
    for j in range(7):
        print threading.current_thread().getName(), '--我在读' + bname
        time.sleep(3)

ts = []  # 创建线程列表
t1 = MyThread(None, listen, '线1', ('一辈子孤单',))
t2 = MyThread(None, read, '线2', ('平凡的世界',))
# 实例化时要根据参数顺序传入,args参数要写成元组形式,一个元素时,加逗号避免歧义
ts.append(t1)
ts.append(t2)
if __name__ == '__main__':
    for t in ts: # 遍历线程列表
        t.setDaemon(True)  # 设为守护线程,主线程结束后所有子线程立即结束,写在start方法前!
        t.start()  # 启动线程
    t.join()  # 在所有子线程结束前一直阻塞主线程的结束,一定写在线程循环外!!写在循环内会成单线程...
    print '主线程:', threading.current_thread().getName(), '结束'

线程的join、setDaemon等方法,想详细了解的点这里点击打开链接

运行结果:

Python中多线程的实现与类的简介_第2张图片

    2.与单线程的简单比较
# coding=utf-8
import threading
import time

'''单线程测试'''
def listen(sname):
    for i in range(7):
        print '我在听' + sname
        time.sleep(2)  # 每次听2秒

def read(bname):
    for j in range(7):
        print '我在读' + bname
        time.sleep(3)  # 每次读3秒

if __name__ == '__main__':
    print'开始时间:', time.ctime()
    listen('一辈子孤单')
    read('平凡的世界')
    print '结束时间:', time.ctime()

'''多线程测试'''
# class MyThread(threading.Thread):  # 定义线程类继承 threading.Thread
#
#     def __init__(self, group, target, name, args):
#         threading.Thread.__init__(self, group, target, name, args)
#         '''重写父类的构造函数。
#            group:线程组,未实现,但实例化时必须有这个参数,设为None
#            target:指向线程要绑定的函数
#            name:线程名
#            args:绑定函数的所需参数,为元组类型
#        '''
#
# def listen(sname):
#     for i in range(7):
#         print threading.current_thread().getName(), '--我在听' + sname
#         time.sleep(2)
#
# def read(bname):
#     for j in range(7):
#         print threading.current_thread().getName(), '--我在读' + bname
#         time.sleep(3)
#
# ts = []  # 创建线程列表
# t1 = MyThread(None, listen, '线1', ('一辈子孤单',))
# t2 = MyThread(None, read, '线2', ('平凡的世界',))
# # 实例化时要根据参数顺序传入,args参数要写成元组形式,一个元素时,加逗号避免歧义
# ts.append(t1)
# ts.append(t2)
# if __name__ == '__main__':
#     # print '开始时间:', time.ctime()
#     for t in ts:  # 遍历线程列表
#         t.setDaemon(True)  # 设为守护线程,主线程结束后所有子线程立即结束,写在start方法前!
#         t.start()  # 启动线程
#     t.join()  # 在所有子线程结束前一直阻塞主线程的结束,一定写在线程循环外!!写在循环内会成单线程...
#     print '主线程:', threading.current_thread().getName(), '结束了'
#     # print '结束时间:', time.ctime()

 测试时注释一方,运行另一方即可。下面是测试结果。

Python中多线程的实现与类的简介_第3张图片Python中多线程的实现与类的简介_第4张图片

       可见,多线程最大的用处就是节约时间,因为它的总用时,只是最耗时的任务所用时间!当然,并不是所有的情况都适合用多线程,总的来说,多线程最适合的应用场景是“I/0密集型任务”。啥?不知道这是什么?那还不快去问问度娘,补充下知识。



你可能感兴趣的:(Python旅程之数据爬取)