0511Python基础-函数名应用-闭包-装饰器

Posted dzh0394

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了0511Python基础-函数名应用-闭包-装饰器相关的知识,希望对你有一定的参考价值。

1、昨日内容回顾

    动态参数

    *args:接受的是所有的位置参数。

    **kwargs:所有的关键字参数。

    形参顺序:位置参数,*args,默认参数,**kwargs

    *的模型用法:

    在函数的定义的时候,*代表聚合。

    在函数的执行的时候,*代表打散。

 

    内置名称空间

    全局名称空间

    局部名称空间

    全局作用域:内置名称空间,全局名称空间

    局部作用域:局部名称空间

    加载顺序:

        内置名称空间 ---> 全局名称空间(程序运行时)---> 局部名称空间(函数执行时)

    取值顺序:

    局部名称空间(函数执行时)---> 全局名称空间(程序运行时)---> 内置名称空间

        LEGB

    执行顺序:

        当代码运行时,从上至下依次执行。

    函数的嵌套。

    global

    1,声明一个全局变量。

    2,更改一个全局变量。

    nonlocal

    1,不能改变一个全局变量。

 2,....

 

2、函数名的应用(第一对象)。

1,直接打印函数名得到的是函数的内存地址 <function func1 at 0x0000000002876B70>

def func1():

    print(666)

print(func1)

 

2,函数名可以赋值运算。

def func1():

    print(666)

f1 = func1

f1()

3, 函数名可以作为函数的参数。

 

def func1():

    print(666)

 

def func2(x):

    x()

    print(555)

func2(func1)

 

4,函数名可以作为容器类数据类型的元素。

 def func1():

    print(666)

 

def func2():

    print(222)

 

def func3():

    print(111)

 

def func4():

    print(777)

l1 = [func1, func2, func3, func4]

for i in l1:

    i()

dic1 = {

    1:func1,

    2:func2,

    3:func3,

    4:func4,

}

dic1[1]()

  

函数名可以当做函数的返回值

 

def func1():

    print(666)

 

 

def func2(x):  # x = func1

    print(222)

    return x

ret = func2(func1)

ret()

 

3、闭包。

内层函数对外层函数非全局变量的引用就叫闭包

判断是不是闭包 函数名.__closure__

返回的None则不是闭包,返回的是cell.... 则是闭包

闭包有什么用?

当执行一个函数时,如果解释器判断此函数内部闭包存在,这样

Python就一个机制,闭包的所在的临时名称空间不会随着函数的执行完毕而消失。

 

def func1():

    name = ‘老男孩‘

 

    def inner():

        print(name)

    inner()

    print(inner.__closure__)  # <cell at 0x000000000282A768: str object at 0x0000000002856E10>

 

func1()

 

 

def func1():

    global name

    name = ‘老男孩‘

 

    def inner():

        print(name)

 

    inner()

    print(inner.__closure__)  # None

func1()

 

思考题

def func():

    def func1():

        name ="老男孩"

    def func2():

        nonlocal name

        name = "alex"

    def func3():

        global name

        name = "太白"

    name = "日天"

 

    func1()

    print(name)  # 1 日天

    func2()

    print(name)  # 2,alex

    func3()

    print(name)  # 3,alex

func()

print(name)  # 4,太白

 

4、装饰器。

装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象。

装饰器的应用场景:比如插入日志,性能测试,事务处理,缓存等等场景

 

import time

‘‘‘第一版本,测试函数low‘‘‘

def login():

    time.sleep(0.3)

    print(‘洗洗更健康...‘)

 

def timmer():

    start_time = time.time()

    login()

    end_time = time.time()

    print(‘此函数的执行时间%s‘ % (end_time - start_time))

timmer()

 

 

改变了我原来执行函数的执行方式,不好

def login():

    time.sleep(0.3)

    print(‘洗洗更健康...‘)

# login()

 

def register():

    time.sleep(0.4)

    print(‘洗洗更健康22222...‘)

# register()

def timmer(f):

    start_time = time.time()

    f()

    end_time = time.time()

    print(‘此函数的执行时间%s‘ % (end_time - start_time))

 

timmer(login)

timmer(register)

 

 

虽然执行函数的方式已经无限接近于原方式,但是更麻烦了,增加了两步代码。改

def login():

    time.sleep(0.3)

    print(‘洗洗更健康...‘)

# login()

 

def timmer(f):

    start_time = time.time()

    f()

    end_time = time.time()

    print(‘此函数的执行时间%s‘ % (end_time - start_time))

 

f1 = login  # 将login函数名给了f1

login = timmer  # 将timmer函数名给了login

login(f1)  # timmer(login)

 

 

初级装饰器

def login():

    time.sleep(0.3)

    print(‘洗洗更健康...‘)

# login()

 

def timmer(f):  # f = login函数名

 

    def inner():

        start_time = time.time()

        f()  # login()

        end_time = time.time()

        print(‘此函数的执行时间%s‘ % (end_time - start_time))

    return inner

 

login = timmer(login)  # inner 此login是新变量

login()  # inner()

 

name = ‘alex‘

name = ‘老男孩‘

 

 

简单版装饰器  语法糖

def timmer(f):  # f = login函数名

    def inner():

        start_time = time.time()

        f()  # login()

        end_time = time.time()

        print(‘此函数的执行时间%s‘ % (end_time - start_time))

    return inner

 

@timmer  # login = timmer(login)  # inner 此login是新变量

def login():

    time.sleep(0.3)

    print(‘洗洗更健康...‘)

login()

 

@timmer  # register = timmer(register)

def register():

    time.sleep(0.2)

    print(‘洗洗更健康22...‘)

 

login()  # inner()

 

被装饰的函数带参数的装饰器

 

def timmer(f):  # f = login函数名

    def inner(*args,**kwargs):  # args (2, 3)

        start_time = time.time()

        f(*args,**kwargs)  # login() *(2, 3) 2,3

        end_time = time.time()

        print(‘此函数的执行时间%s‘ % (end_time - start_time))

    return inner

 

@timmer  # login = timmer(login)  # inner 此login是新变量

def login(a,b):

    print(a,b)

    time.sleep(0.3)

    print(‘洗洗更健康...‘)

 

login(2,3)  # inner(2,3)

 

@timmer  # register = timmer(register)

def register(a):

    time.sleep(0.2)

    print(‘洗洗更健康22...‘)

 

register(1)  # inner(1)

 

def func1(x):

    x = 0

    print(x)

func1(0)

 

函数带返回值的装饰器 (万能装饰器)

def timmer(f):  # f = login函数名

    def inner(*args,**kwargs):  # args (2, 3)

        start_time = time.time()

        ret = f(*args,**kwargs)  # login() *(2, 3) 2,3

        end_time = time.time()

        print(‘此函数的执行时间%s‘ % (end_time - start_time))

        return ret

    return inner

 

@timmer  # login = timmer(login)  # inner 此login是新变量

def login(a,b):

    print(a,b)

    time.sleep(0.3)

    print(‘洗洗更健康...‘)

    return 666

 

print(login(2,3))  # inner(2,3)

 

 

 

def wrapper(f):

    def inner(*args,**kwargs):

        ‘‘‘执行被装饰函数之前的操作‘‘‘

        ret = f(*args,**kwargs)

        """执行被装饰函数之后的操作"""

        return ret

    return inner

 

装饰器功能:在不改变原函数的基础上,为原函数增加一些额外的功能,log,登录注册,等等.

 

以上是关于0511Python基础-函数名应用-闭包-装饰器的主要内容,如果未能解决你的问题,请参考以下文章

python 基础篇 11 函数进阶----装饰器

python 学习 D11 函数名的应用(第一对象) 闭包 装饰器

python基础

Python基础高阶函数+函数嵌套+闭包 ==装饰器

python函数下篇装饰器和闭包,外加作用域

Python基础(十三)