• sys&faker&jsonpath模块、异常处理、多线程、多进程


    1.sys模块

    sys.argv 能获取运行文件时,文件名后面所传参数。结果是一个列表。
    import sys
    print(sys.argv)  #获取运行python文件的时候传入的参数,会连同文件名,和参数,返回一个列表。
    #在terminal里运行,才能传参。如在当前目录下,运行 python sys模块.py arg1
    
    if len(sys.argv)>1:
        if sys.argv[1]=='--help':
            quit('这个python是用来测试的,运行的时候需要使用 python a.py port')
        else:
            port = sys.argv[1]
    else:
        port = 7878
    
    import flask
    server = flask.Flask(__name__)
    
    @server.route('/')
    def index():
        return '<h1>首页</h1>'
    
    server.run(port=port)

    运行上边代码,返回:

    2.faker模块

    import faker
    f = faker.Faker(locale='zh_CN') #实例化,并指定语言为中文
    print(f.name())#姓名
    print(f.credit_card_number())#随机信用卡号
    print(f.email())#随机信用卡号
    print(f.ipv4())#随机ip地址
    print(f.user_name())#随机用户名
    print(f.phone_number())#随机电话
    print(f.ssn())#随机身份证号

    3.jsonpath模块

    d={
            "error_code": 0,
            "stu_info": [
                    {
                            "id": 2059,
                            "name": "小白",
                            "sex": "",
                            "age": 28,
                            "addr": "河南省济源市北海大道32号",
                            "grade": "天蝎座",
                            "phone": "18378309272",
                            "gold": 10896,
                            "info":{
                                    "card":6214234235232352,
                                    "bank_name":'中国银行',
                                    "name":'zff'
                            }
                    }
            ],
            'name':'哈哈哈'
    }
    
    #普通取name
    res = d['stu_info'][1]['name']
    print(res)
    
    # jsonpath取name
    import jsonpath
    res = jsonpath.jsonpath(d,'$..name') #模糊匹配,不管层次与位置.$代表外部大字典,..代表任意的。。
    
    #res2 = d['stu_info'][0]['info']['bank_name']
    #res2=jsonpath.jsonpath(d,'$.['stu_info'][0]['info']['bank_name']')
    #这2个res2效果是一样的

    4.面向对象——继承

    在父类某个方法的基础上再增加新功能:
    super().xxx()
    super()会自动找到父类
    class Car:
        def run(self,):
            print('running...')
            return 'abc'
    
    
    class NewCar(Car):
        def run(self):
            res = super().run()# 保留父类run的方法,super()的意思就是找到父类
            #res=Car().run() #与上边super功能一样,但父类名称改的时候,他也得改
            print('fly...',res)
    
    
    bmw = NewCar()
    bmw.run()

    5.异常处理

    处理异常,将出错的情况进行处理,使出错时抛出提示或要求继续某种操作,而不是报错让程序进行不下去。
    用 try: xxx except Exception as e: print('提示语')

    try和except是必须的,else和finally选用。

    try:
        res = 1 / 0
    except ZeroDivisionError as e:
    #except ZeroDivisionError,e: #python2不能用as,要用,
        print('出错啦,除数不能为0',e)
    
    l = list()
    l.append(1)
    d = dict()
    # d['name']='abc'
    try:
        print(d['name'])
        print(l[-1])
    except IndexError as e: #只能捕捉到越界下标错误
        print('出错了,下标越界',e)
    except KeyError as e:
        print('字典key不存在',e)
    except Exception as e: #能捕捉各种异常,但不会界定是何种异常
        print('未知异常',e)
    else:
        print('没有出现异常。。。')
    finally: #不管异常是否出现,都会执行,使用场景:打开文件或数据库,出错了,但也得关闭
        print('什么时候执行finally')
    
    dic = {}
    print(dic['name'])
    
    class NumberError(Exception):
        pass
    
    class M:
        def main(self):
            count = input('请输入要产生多条银行卡号:').strip()
            if not count.isdigit():
                raise NumberError('输入的数字不对') #主动抛出异常,判断为一个什么时候,终止运行
                #raise Exception('自定义异常')
    m = M()
    m.main()

    6.多线程

    线程:程序执行的最小单位。

    为什么有时候单线程比主线程快?

    电脑CPU有几个核心,就同时只能运行几个线程。
    感觉多线程运行。很快,其实并没有,只是CPU运行速度特别快,切换速度特别快
    全局解释器锁,叫GIL。python加了个锁,让每个CPU只运行一个线程,避免数据错乱。

    单线程:没有做多线程,就是单线程

    多线程:利用for语句,启动多个线程

    for i in range(20): #启动了多个线程
    t1 = Thread(target=run,)
    t1.start()

    主线程等待子线程执行任务:t.join()

    while threading.active_count()!=1: #判断子线程是否执行结束,这种简单
    pass
    #运行程序规则:首先由一个线程,会将代码从头到尾执行一遍。
    import threading #该模块提供线程
    from threading import Thread
    import time
    
    def run():
        time.sleep(1)
        print('run...')
    
    start_time = time.time() #
    
    for i in range(5):  #串行,得5s,单线程运行
        run()
    
    threads = []
    
    for i in range(20): #启动了多个线程
        t1 = Thread(target=run,)
        t1.start()
        #t1.join() #这儿不能加,否则会变成串联线程,即单线程
        
        # threads.append(t1) 
    # for t in threads: #循环,同时等待多个线程
    #     t.join()
    #这一部分是一个等待代码
    
    while threading.active_count()!=1: #判断子线程是否执行结束,这种比上边等待代码块简单
        pass
    
    end_time = time.time()
    
    print(end_time - start_time)

    7.多进程

    用法上跟多线程特别相似

    进程:
    一些资源的集合。如qq, 图片,程序
    一个进程里面最少有一个线程, 主线程。
    一个进程可以包含多个线程
    可以利用多个cpu的。

    IO密集型任务: 即input output,分为磁盘io和网络io
    IO消耗比较多的,适合多线程

    CPU密集型任务:消耗CPU多的,适合多进程
    为啥python的多线程利用不了多核CPU,但是咱们看起来的时候还是并发的?
    因为在Python多线程下,每个线程的执行方式:
    1、获取GIL
    2、执行代码直到sleep或者是python虚拟机将其挂起。
    3、释放GIL

    可见,某个线程想要执行,必须先拿到GIL,我们可以把GIL看作是“通行证”,
    并且在一个python进程中,GIL只有一个。拿不到通行证的线程,就不允许进入CPU执行。
    import multiprocessing
    import time
    import threading
    import requests
    
    def run():
        time.sleep(10)
        print('run...')
    
    if __name__ == '__main__':
        for i in range(10):
            p = multiprocessing.Process(target=run)
            p.start()
        while multiprocessing.active_children(): #等待其他子进程运行结束
            pass

    8.守护线程 

    守护主线程,主线程执行完成之后,子线程立即结束。如秦始皇死,相关人都得死。
    import threading
    import time
    def run():
        time.sleep(5)
        print('run。。。')
    
    for i in range(100):
        puren = threading.Thread(target=run)
        puren.setDaemon(True)#设置子线程为守护线程。如果不加,这个会运行100次run.加了后,运行一次。
        puren.start()
    
    print('over')
    
    #即不加等待,主线程一运行完,子线程就停止运行。

    9.锁

    多个线程同时去操作同一个数据的时候,可能会导致数据不正确。
    要把这个数据机上锁,这样同时就只能有一个线程在操作这个数据了。
    python3会自动加锁,所有写不写加不加锁代码没所谓
    import threading
    
    count = 0
    
    lock = threading.Lock()  #申请一把锁
    
    def run():
        global count
        with lock:
            count+=1
        # lock.acquire()#加上锁
        # count+=1
        # lock.release()#释放,必须的,要么会停着不动
            #这3行代码跟上边功能一样
            #python里边不加锁也行,因为python3会自动加锁
    
    for i in range(10):   #多个线程都要去操作count数据
        t = threading.Thread(target=run)
        t.start()
    
    while threading.active_count()!=1:
        pass
    
    print(count)

    10.牛刀小试

    生成尾号为11的银行卡号:

    # 10
    #工商银行:6222342
    #广发银行:34634
    
    #1、获取数据,把不需要的数据过滤掉
    import random
    import string
    class BankCardId:
        file_name = 'card_no'
        all = []  # 保存所有有效的数据
    
        def __init__(self):#自动调用函数,取到all
            self.get_data()
    
        def get_data(self): #取到最后俩位数为11的数据,all取到[['工商银行', '18', '620200'], ['工商银行', '18', '620302'],...]
            with open(self.file_name,encoding='utf-8') as fr:
                for line in fr:
                    if line.strip():#判断不是空行
                        new_line = line.split()[1:]
                        a,b = new_line[-1],new_line[-2] #获取末尾2个元素
                        if a==b=='1':#判断末尾2个元素是不是都是1
                            self.all.append(new_line[:3])
    
        def get_card(self): #生成银行卡号
            bank_name,lenth,start = random.choice(self.all)
            other_lenth = int(lenth) - len(start) - 2
            other = ''.join( random.choice(string.digits) for i in range(other_lenth) )
            res = start + other + '11'
            print(bank_name,self.my_print(res))
    
        def my_print(self,s):
            count = 0
            new_s = ''
            for i in s:
                count += 1
                new_s += i
                if count == 4:
                    new_s += ' '
                    count = 0
            return new_s
    
        def main(self):
            num = input('请输入要产生多少条:').strip()
            for i in range(int(num)):
                self.get_card()
    
    
    b = BankCardId()
    # b.get_data()
    # print(b.all)
    b.main()

    下载网页图片:

    import threading
    import requests
    import random
    import time
    from hashlib import md5
    res = []
    def down_load_pic(url):
        #下载图片的url
        r = requests.get(url)
        file_name = md5(r.content).hexdigest()#把文件md5之后字符串当做文件名
        with open(file_name+'.jpg','wb') as fw:
            fw.write(r.content)
        print('%s下载完成'%file_name)
        res.append(file_name)
    
    urls = [
        'http://www.nnzhp.cn/wp-content/uploads/2018/12/110405th7jtus7gjjlywnl.jpg',
        'http://www.nnzhp.cn/wp-content/themes/QQ/images/thumbnail.png',
        'http://www.nnzhp.cn/wp-content/uploads/2018/08/f38a12137574f4333f7686f7e75a06fb8bd9fed537ea59-pRwNuK_fw658.jpeg',
        'http://www.nnzhp.cn/wp-content/uploads/2018/08/c1bba9a47cfe8fe7000f137f020ad623.png',
    ]
    
    start_time = time.time()
    
    #单线程
    # for url in urls:
    #     down_load_pic(url)
    
    #多线程
    for url in urls:
        t = threading.Thread(target=down_load_pic,args=(url,) )
        t.start()
    
    while threading.active_count()!=1:#等待子线程运行完成
        pass
    
    print(res)
    
    end_time = time.time()
    
    print('下载完成,下载时间是 %s'% (end_time-start_time))
    
    # 下载完成,下载时间是 107.56531095504761,单线程
    # 下载完成,下载时间是 81.53419184684753 多线程
    
    


  • 相关阅读:
    Ruby 2
    Ruby 1
    莱布尼兹:与牛顿争吵了一生的斗士 微积分的奠基人之一―莱布尼茨
    如何实现html页面自动刷新
    css z-index的层级关系
    让网页变灰的实现_网站蒙灰CSS样式总汇
    利用CSS变量实现炫酷的悬浮效果
    离线电商数仓(十四)之系统业务数据仓库数据采集(一)电商业务简介
    离线电商数仓(十三)之用户行为数据采集(十三)采集通道启动/停止脚本
    离线电商数仓(十)之用户行为数据采集(十)组件安装(六)采集日志Flume(二)消费Kafka数据Flume
  • 原文地址:https://www.cnblogs.com/fangfangzhang/p/10925330.html
Copyright © 2020-2023  润新知