10Python学习修饰器&生产消费模型&作用域

一、生产消费模型

场景:一个生产商品,一个消费商品。如果生产商把所有商品生产完毕后,再丢给消费,效率极其低下。

测试代码如下:

import time
def producer(num):
    res_l = []
    for i in range(1, num + 1):
        time.sleep(0.1)
        print("产品{}生产完毕".format(i))
        pro_s = "产品{}".format(i)
        res_l.append(pro_s)
    return res_l					#全部生产完毕后,交给消费端。如果有亿万级别的数据,内存消耗高

def consumer(product_l):
    for i in product_l:
        print("消费{}".format(i))

start = time.time()
consumer(producer(50))
end = time.time()
print("花费 %.2f秒" %(end-start))

# 输出 花费 5.15秒

使用生产消费模型改写

import time
def producer(num):
    for i in range(1, num + 1):
        time.sleep(0.1)
        print("产品{}生产完毕".format(i))
        pro_s = "产品{}".format(i)
        yield pro_s					# 通过生成器函数,生产一个返回一个,节约资源

def consumer(product):
    while 1:
        for i in product:		# 消费端死循环,调用生成器next方法进行消费。
            print("消费",i)
        break
start = time.time()
consumer(producer(50))
end = time.time()
print("花费 %.2f秒" %(end-start))

二、修饰器

修饰器本质就是函数

修饰器的特性:1、不修改原函数调用方式及代码 2、为该函数提供额外的功能

其公式为 修饰器 = 高阶函数 + 函数嵌套 + 闭包(变量作用域)

为了能更好的掌握修饰器,对前面只是进行复习

2.1 高阶函数

高阶函数:可以通过函数作为参数传递 或 返回值是一个函数

# 通过参数来接收一个函数变量,并调用
def high_f1(func):
    func()

# 通过返回值来返回一个函数变量
def high_f2():
    return foo

# 既通过函数参数传递,还返回一个函数变量
def high_f3(func):
    return func
  
# 普通函数
def foo():
    print("hell foo")

high_f1(foo)
high_f2()()
high_f3(foo)()

2.2 函数嵌套

函数嵌套,即函数中再定义了个函数。在python中,函数即变量的原则。所以这种方式是被允许的。

Python 3.7.2 (default, Feb 12 2019, 08:15:36) 
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def fun1():
...     print("from fun1...")
...     def fun2():
...         print("from fun2..")
...         def fun3():
...             print("from fun3...")
...         fun3()
...     fun2()
... 
>>> fun1()
from fun1...
from fun2..
from fun3...

2.3 变量的作用域

变量的作用域一般都是寻找自己层级,如果没有再向外一层级寻找。

>>> def fun1(name):
...     print("from fun1...",name)		# 使用传递的name
...     def fun2():
...         print("from fun2..",name)	# 本层级作用域没有找到name变量,向上一级寻找name
...         def fun3():
...             name = "bb"
...             print("from fun3...",name) # 本层级找到name变量,直接使用
...         fun3()
...     fun2()
... 
>>> fun1("aa")
from fun1... aa
from fun2.. aa
from fun3... bb

2.3.1 global关键字

一般局部作用域中,无法对全局作用域中的变量进行修改。但是使用了global关键,使得这种场景变成可能。

name = "hello"
def fun1(name):
    print("from fun1...",name)      #使用形参变量
    def fun2():
        global name
        name = "world"              #修改全局变量name
        print("from fun2..",name)   #自己作用域中没有该变量,使用全局作用域变量
        def fun3():
            print("from fun3...",name)#自己作用域中没有该变量,使用全局作用域变量
        fun3()
    fun2()

fun1("aa")
# from fun1... aa
# from fun2.. world
# from fun3... world
print(name)
# world

2.3.2 nonlocals关键字

但是有这么一种场景,需要修改上层作用域的变量,不修改全局作用域变量。那么此时需要使用nonlocals来实现

name = "全局作用域"
def fun1():
    name = "fun1"
    print("from fun1...",name)      #使用形参变量
    def fun2():
        nonlocal name
        name = "nonlocal"              #修改全局变量name
        print("from fun2..",name)   #自己作用域中没有该变量,使用全局作用域变量
        def fun3():
            print("from fun3...",name)#自己作用域中没有该变量,使用全局作用域变量
        fun3()
    fun2()

fun1()
# 打印如下
# from fun1... fun1
# from fun2.. nonlocal
# from fun3... nonlocal
print(name)
# 全局作用域

2.4 使用修饰器

2.4.1 需求,对A函数增加时间统计功能

在不修改调用方式,不修改函数内部代码的大前提下。A函数如下

def A():
    for i in range(5):
        print("hi:%s" % i)


# 调用A函数
A()

使用修饰器函数进行增加功能

import time

def timer(func):
    def wapper():
        start_time = time.time()
        func()									#寻找上层作用域func并调用
        end_time = time.time()
        print("执行时间:%s" % (end_time - start_time))
    return wapper

@timer		#通过timer函数来传递A的函数名作为参数
def A():
    for i in range(5):
        print("hi:%s" % i)

# 调用A函数
A()


# 输出:
# hi:0
# hi:1
# hi:2
# hi:3
# hi:4
# 执行时间:8.821487426757812e-05
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值