day10闭包、函数装饰器

一、函数名的本质

  函数名本质上就是函数的内存地址、或者说函数名就是普通的变量

1、可以被赋值引用

def func1():
    print(666)

f1 = func1
f1()
        

2、可以被当作容器类型的元素

def func1():
    print(666)

def func2():
    print(222)

list = [func1,func2]
for i in list:i()

3、函数名可以当作函数参数传给函数

def func1():
    print(666)


def func3(x):
    x()

func3(func1)

二、闭包:

  闭包函数:内部函数包含对外部作用域而非全剧作用域变量的引用,该内部函数称为闭包函数。#函数内部定义的函数称为内部函数

  由于有了作用域的关系,我们就不能拿到函数内部的变量和函数了。如果我们就是想拿怎么办呢?返回呀!

  我们都知道函数内的变量我们要想在函数外部用,可以直接返回这个变量,那么如果我们想在函数外部调用函数内部的函数呢?

  是不是直接就把这个函数的名字返回就好了?

这才是闭包函数最常用的用法

def func():
    name = 'eva'
    def inner():
        print(name)
    return inner

f = func()
f()

判断闭包函数的方法__closure__

#输出的__closure__有cell元素 :是闭包函数
def func():
    name = 'eva'
    def inner():
        print(name)
    print(inner.__closure__)
    return inner

f = func()
f()

#输出的__closure__为None :不是闭包函数
name = 'egon'
def func2():
    def inner():
        print(name)
    print(inner.__closure__)
    return inner

f2 = func2()
f2()
def wrapper():
    money = 1000
    def func():
        name = 'eva'
        def inner():
            print(name,money)
        return inner
    return func

f = wrapper()
i = f()
i()
闭包嵌套

三、装饰器:

1、什么叫装饰器:

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

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

2、完整装饰器和装饰器的执行流程:

装饰器@的功能:   1、自动执行outer函数并将其下面的函数名func1当作参数传递
2、将outer函数的返回值返回,并重新赋值给func
def outer(func):
    def inner(*args,**kwargs):
        print('欢迎光临')
        r = func(*args,**kwargs)
        print('下次再来')
        return r
    return inner


@outer
def  func1():
    print('欧美专区')
    return 111
@outer
def func2():
    print('日韩专区')
    return 222
@outer
def func3():
    print('国产专区')
    return 333

print(func1())
print(func2())
print(func3())

 

 3、开放封闭原则:

  1.对扩展是开放的

    为什么要对扩展开放呢?

    我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。

  2.对修改是封闭的

    为什么要对修改封闭呢?

    就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。

    装饰器完美的遵循了这个开放封闭原则。

4、装饰器的固定格式:

def wrapper(func):
    def inner(*args,**kwargs):
        """执行被装饰函数之前的操作"""
        ret = func(*args,**kwargs)
        """执行被装饰函数之后的操作"""
        return ret
    return inner

猜你喜欢

转载自www.cnblogs.com/feige6/p/9024932.html