zoukankan      html  css  js  c++  java
  • python 装饰器

    一.简介

      在学习介绍装饰器之前 ,我们需要了解函数 是对象,函数 的特性是:

    • 函数可以赋值给一个变量
    • 函数可以定义在另一个函数内部

    即,这也意味着一个函数可以返回另一个函数

    装饰器就是封装器,可以让你在被装饰函数之前或之后执行代码,而不必修改函数本身

    所以:

    装饰器是一个修改函数、或方法、或类的函数

     自定义装饰器  

    def out(inner):
        def fun():
            print("before")
            inner()
            print("after")
        return fun
    def inner():
        print("center")
    inner()
    
    mydecorated = out(inner)
    mydecorated()

    使用装饰器

    def outer(fun):
        def inn():
            print("hello")
            r = fun() #== f1()
            return r
        return inn
    @outer
    def f1():
        print("test")
    f1()

    装饰器只是装饰器设计模式的python实现,装饰器可以嵌套

    #例2
    def
    out(func): def inn(a,b): print('test') r = func(a,b) return r return inn @out def fun1(a, b): sum1 = a + b print(sum1) fun1(1, 2)

    装饰器传参

    通过在形参列表中使用 *args 语法,python函数能够接收可变数量的位置参数(positional arguments)。 *args 会将所有没有关键字的参数放入一个参数元组中,在函数里可以访问元组中的参数。相反,将 *args 用于函数调用时的实参列表之时,它会将参数元组展开成一系列的位置参数

    **kwargs 与 *args 的行为类似,但用于关键字参数而非位置参数。如果在函数的形参列表中使用 **kwargs ,它会收集函数收到的所有额外关键字参数,放入一个字典中。如果用于函数的实参列表,它会将一个字典展开为一系列的关键字参数

    def funtion_with_many_keyword_args(**kwargs):
        print(kwargs)
    
    funtion_with_many_keyword_args(a='apples', b='bananas', c='cantalopes')
    **kwargs示例
    def multiply_name(count=0, name=''):
        print(name * count)
    
    arg_dict = {'count': 3, 'name': 'Brian'}
    
    multiply_name(**arg_dict)
    *args示例
    def outer1(func):
        def inner(*args,**kwargs):
            print("123")
            ret = func(*args,**kwargs)
            print("123")
            return ret
        return inner
    def outer2(func):
        def inner(*args,**kwargs):
            print("456")
            ret = func(*args,**kwargs)
            print("456")
            return ret
        return inner
    @outer1
    @outer2
    def f():
        
        return "ok"
    
    r = f()
    print(r)
    
    #打印结果:
    456
    123
    ok
    
    # 1、执行outer2函数,将f作为outer2函数的参数,将f赋值给func
    # 2、得到返回值inner,重新赋值给f:f = inner  ==>  f() = inner()
    # 3、执行outer1函数,将整个inner函数作为outer1函数的参数
    # 4、得到返回值inner,再重新赋值给f:f == inner  ==> f() = inner()
    # 5、因为装饰器只有两层,就不用再执行下一个装饰器函数,如果更多层就继续循环以上程序过程
    # 6、下面就执行最终的inner函数,执行func函数时,就是执行最原始的f函数
    装饰器传参

    使用装饰器语法,鸟瞰其中发生的事情(以例2为例):

    1. 解释器到达被装饰的函数,编译fun1函数,并将其命名为 'fun1'。
    2. 然后将该函数传递给装饰行中指定的装饰器函数(out)。
    3. 装饰器函数(通常是用来包装原函数的另一个函数)的返回值取代原来的函数(fun1),绑定到变量名 fun1 
  • 相关阅读:
    vue hover如何触发事件?
    防止 window.open 被拦截
    input输入框change和blur事件区别
    神马?使用JS直接上传并预览粘贴板的图片?
    删除设备与驱动器中百度网盘图标
    枚举类字典代码 草稿
    中文转换成阿拉伯数字
    Java对象与类中的一个小练习
    正向代理和反向代理
    MySQL教程126-MySQL事务隔离级别
  • 原文地址:https://www.cnblogs.com/jl-bai/p/5616514.html
Copyright © 2011-2022 走看看