面向对象进阶8.9

一、生成器:

1、函数

def A():
    for i in range(10):
        yield i    →     ##将函数变成一个迭代器(生成器)
a=A()
print(next(a))
print(next(a))
  输出:0
       1

 

2、try、except;

尝试执行try中的代码,如果有错,则被except捕获,但是整个程序不会崩溃,
def A():
    for i in range(5):
        yield i        ##将函数变成一个迭代器(生成器)
try:
    a=A()
    print(next())
    print(next())
    print(next())
    print(next())
    print(next())
    print(next())
except Exception as e:
    print(e)
print('Hello world')
输出:0
1
2
3
4
     Hello world

二、装饰器:

 

def deco(func):
    def warp(name1):
        print('warp')
        name1 = 10000
        return func(name1)
    return warp
@deco
def jy(name):
    print(name)
jy('zxy')
输出:warp
10000

 

1、不定长参数

1.1   *args 位置传参

 

def haha(*args):
    print(args)
haha(1,2,3,4)
输出:(1,2,3,4) 元组

 

1.2   **kwargs带参数名称传参

 

def lala(**kwargs):
    print(kwargs)
lala(a=1,b=2,c=3)
输出:{'a': 1, 'b': 2, 'c': 3} 字典
↓ ↓
键名 键值

1.3   *args 和 **kwargs 混合掺活

 ## *args 一定要放前面

def heihei(*args,**kwargs):
    print(args)
    print(kwargs)
heihei(1,2,3,a=1,b=2,c=3)
输出:(1, 2, 3)
     {'a': 1, 'b': 2, 'c': 3}

2、装饰器代参

def deco2(param):
    print(param)
    def deco(func):
        def warp(*args,**kwargs):
            print(args)
            print(kwargs)
            kwargs['name2']=10000
            return func(*args,**kwargs)
        return warp
    return deco
@deco2(100)
def lele(name2):
    print(name2)
lele(name2='jy💗zxy')
输出:100
()
     {'name2': 'jy💗zxy'}
     10000

三、进程和线程

1、并发和并行

    1.1  并发:间隔发生     ←   线程  (伪并行)

    1.2  并行:同时进行     ←   进程  (多个CPU进行操作)

2、高并发:短时间内大量访问和请求;例如 →  天猫双11活动

      通过设计保证系统能够同时并行处理很多请求;

3、进程:

创建、就绪、运行、阻塞、结束

进程的概念主要有两点:

第一,进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。

第二,进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,我们称其为进程。

进程是操作系统中最基本、重要的概念。是多任务系统出现后,为了刻画系统内部出现的动态情况,描述系统内部各程序的活动规律引进的一个概念,所有多任务设计操作系统都建立在进程的基础上。

四、python中的多进程

调用fork()函数的是父进程,创建出的是子进程,子进程是父进程的一个拷贝,但是子进程拥有自己的PID。fork()函数非常特殊它会返回两次,父进程中可以通过fork()函数的返回值得到子进程的PID,而子进程中的返回值永远都是from random import ranfrom time import time, sleep

def download_task(filename):
    print('开始下载%s...' % filename)
    time_to_download = randint(5, 10)
    sleep(time_to_download)
    print('%s下载完成! 耗费了%d秒' % (filename, time_to_download))
def main():
    start = time()
    download_task('Python从入门到住院.pdf')
    download_task('Peking Hot.avi')
    end = time()
    print('总共耗费了%.2f秒.' % (end - start))
if __name__ == '__main__':
    main()
输出:

开始下载Python从入门到住院.pdf...

  Python从入门到住院.pdf下载完成! 耗费了6秒
  开始下载Peking Hot.avi...
  Peking Hot.avi下载完成! 耗费了7秒
  总共耗费了13.01秒.

从上面的例子可以看出,如果程序中的代码只能按顺序一点点的往下执行,那么即使执行两个毫不相关的下载任务,也需要先等待一个文件下载完成后才能开始下一个下载任务,很显然这并不合理也没有效率。接下来我们使用多进程的方式将两个下载任务放到不同的进程中,代码如下所示。

from multiprocessing import Process
from os import getpid
from random import randint
from time import time, sleep
def download_task(filename):
    print('启动下载进程,进程号[%d].' % getpid())
    print('开始下载%s...' % filename)
    time_to_download = randint(5, 10)
    sleep(time_to_download)
    print('%s下载完成! 耗费了%d秒' % (filename, time_to_download))
def main():
    start = time()
    p1 = Process(target=download_task, args=('Python从入门到住院.pdf', ))
    p1.start()
    p2 = Process(target=download_task, args=('Peking Hot.avi', ))
    p2.start()
    p1.join()
    p2.join()
    end = time()
    print('总共耗费了%.2f秒.' % (end - start))
if __name__ == '__main__':
    main()
输出:
总共耗费了0.40秒.

在上面的代码中,我们通过Process类创建了进程对象,通过target参数我们传入一个函数来表示进程启动后要执行的代码,后面的args是一个元组,它代表了传递给函数的参数。Process对象的start方法用来启动进程,而join方法表示等待进程执行结束。运行上面的代码可以明显发现两个下载任务“同时”启动了,而且程序的执行时间将大大缩短,不再是两个任务的时间总和。

五、python中的多线程

多线程类似于同时执行多个不同程序,多线程运行有如下优点:

  • 使用线程可以把占据长时间的程序中的任务放到后台去处理。
  • 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度
  • 程序的运行速度可能加快
  • 在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等
from random import randint
from threading import Thread
from time import time, sleep


def download(filename):
    print('开始下载%s...' % filename)
    time_to_download = randint(5, 10)
    sleep(time_to_download)
    print('%s下载完成! 耗费了%d秒' % (filename, time_to_download))


def main():
    start = time()
    t1 = Thread(target=download, args=('Python从入门到住院.pdf',))
    t1.start()
    t2 = Thread(target=download, args=('Peking Hot.avi',))
    t2.start()
    t1.join()
    t2.join()
    end = time()
    print('总共耗费了%.3f秒' % (end - start))


if __name__ == '__main__':
    main()
输出:
开始下载Python从入门到住院.pdf...开始下载Peking Hot.avi...

Python从入门到住院.pdf下载完成! 耗费了7秒
Peking Hot.avi下载完成! 耗费了7秒
总共耗费了7.033秒

 

posted @ 2019-08-09 16:50  胖虎不胖  阅读(208)  评论(0编辑  收藏  举报