• 函数名 闭包 装饰器


    函数名的应用(第一对象):
    第一对象(first-class object)指
    1,可在运行期创建
    2,可用作函数参数或返回值
    3,可存入变量的实体。
    函数的应用:
    1,直接打印函数名,得到的是函数的内存地址
    def func1():
        print(666)
    print(func1)   # func1没有(),只打印函数名,没有执行
    View Code
    2,函数名可以赋值运算
    def func1():
        print(666)
    f1 = func1
    f1()   就等于func1() ,所以执行函数  #  666
    View Code
    3,函数名可以作为函数的参数。
    def func1():
        print()
    def func2(x):
        x()
        print(555)
    func2(func1)   ###555
    View Code
    4,函数名可以作为容器类数据类型的元素。
    def func1():
        print(666)
    def func2():
        print(222)
    def func3():
        print(111)
    def func4():
        print(777)
    lis = [func1 ,func2 ,func3 ,func4]
    for i in lis:
        (i)
    dic1 = {
        1:func1,
        2:func2,
        3:func3,
        4:func4,
    }
    dic1[1]()
    View Code
    5,函数名可当函数的返回值。
    def func1():
        print(666)
    def func2(x):
        print(222)
        return x
    ret = func2(func1)
    ret()  #    222    666
    View Code
    添加
    l1 = []
    for i in range(1,101):
        l1.append('func%d'%i)
    print(l1)
    View Code
    闭包:
    内层函数对外层函数非全局变量的引用就叫闭包。
    在内层函数中访问外层函数的局部变量,叫闭包。这个时候局部变量将会常驻内存。 判断是不是闭包 函数名.
    __closure__ 返回的None则不是闭包,返回的是cell...则是闭包
    闭包的目的:让内存永远记住一个变量 闭包有什么用? 当执行一个函数时,如果解释器判断此函数内部闭包存在,这样python就一个机制,闭包的所在的临时名称空间不会随着函数的执行完毕而消失。
    def func1():
        name = '老男孩'
    
        def inner():
            print(name)
        inner()
    func1()
    View Code
    不是闭包
    def func1():
        global name
        name = '老男孩'
    
        def inner():
            print(name)
        inner()
    func1()
    View Code
    def func1(x):
        def inner():
            print(name)
        inner()
    name = '老男孩'
    func1(name)
    View Code
    判断是不是闭包:
    闭包:
    def func1():
        name = '老男孩'
        def inner():
            print(name)
        inner()
        print(inner.__closure__)
    func1()  #<cell at 0x0000000001DF65B8: str object at 0x0000000001DF8BD0>
    View Code
    def func1(x):
        def inner():
            print(x)
        inner()
        print(inner.__closure__)
    name = '老男孩'
    func1(name)   
    View Code
    非闭包:
    def func1():
        global name
        name = '老男孩'
        def inner():
            print(name)
        inner()
        print(inner.__closure__)  #None
    func1()
    View Code
    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,太白
    执行顺序
    from urllib.request import urlopen
    def index():
        url = "http://www.xiaohua100.cn/index.html"
        def get():
            return urlopen(url).read()
        return get
    xiaohua = index()
    content = xiaohua()
    print(content)
    爬虫一个网站

    装饰器:

    装饰器功能:在不改变原函数的基础上,为原函数增加一些额外的功能,log,登录注册,等等.
    装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象。
    装饰器的应用场景:比如插入日志,性能测试,事务处理,缓存等等场景
    import time
    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()
    第一版本,测试函数low
    import time
    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)
    改变了我原来执行函数的执行方式,不好
    import time
    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)
    虽然执行函数的方式已经无限接近于原方式,但是更麻烦了,增加了两步代码。改
    初级装饰器
    import time
    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 = '老男孩'
    View Code
    简单版装饰器  语法糖
    import time
    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()
    View Code
    被装饰的函数带参数的装饰器
    import time
    #
    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)
    View Code
    函数带返回值的装饰器 (万能装饰器)
    import time
    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)
    View Code

    简单版装饰器默写:

    def wrapper(f):
        def inner(*args,**kwargs):
            '''执行被装饰函数之前的操作'''
            ret = f(*args,**kwargs)
            """执行被装饰函数之后的操作"""
            return ret
        return inner
    View Code
    语法糖装饰器默写:
    def wrapper(f):
        def inner(*args,**kwargs):
            ret = f(*args,**kwargs)
            return ret
        return inner
    @wrapper
    def func():
        print(11)
    func()
    View Code
    装饰器的本质是闭包。
    开放封闭原则。
    什么是开放封闭原则?
    1.对扩展是开放的
        为什么要对扩展开放呢?
        我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。
      2.对修改是封闭的
        为什么要对修改封闭呢?
        就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。
    装饰器完美的遵循了这个开放封闭原则。
          
    def wrapper(f): # f = func3函数名
    
        def inner(*args, **kwargs):
            print(333)
            ret = f(*args, **kwargs)  # func3(*(1,2))
            print(666)
            return ret  # 555
        return inner
    
    
    # @wrapper  # func1新变量 = wrapper(func1) = inner
    # def func1():
    #     print(111)
    # func1()  # inner()
    
    # @wrapper  # func2(新变量) = wrapper(func2)      = inner
    # def func2(a, b):
    #     print(a, b)
    
    # func2(1,2)  # inner(1,2)
    
    @wrapper  # func3新变量 = wrapper(func3)     = inner
    def func3(a, b):
        print(a, b)
        return 555
    
    print(func3(2,3)) # inner(2,3)
    View Code
  • 相关阅读:
    R语言实战(四)回归
    nginx无法启动: libpcre.so.1/libpcre.so.0: cannot open shared object file解决办法
    nginx无法启动: libpcre.so.1/libpcre.so.0: cannot open shared object file解决办法
    nginx无法启动: libpcre.so.1/libpcre.so.0: cannot open shared object file解决办法
    nginx无法启动: libpcre.so.1/libpcre.so.0: cannot open shared object file解决办法
    Debian安装fail2ban来防止扫描
    Debian安装fail2ban来防止扫描
    Debian安装fail2ban来防止扫描
    Debian安装fail2ban来防止扫描
    字典转Json
  • 原文地址:https://www.cnblogs.com/ls13691357174/p/9102499.html
Copyright © 2020-2023  润新知