python中的装饰器

原理:开头总要先说几句废话

装饰器是一种对闭包的使用方式。通过查看它的 func_closure 属性可以看出函数闭包特性。
真正理解装饰器有这么几个东西一定要透彻理解:

  1. 变量作用域LEGB
  2. 函数是顶级对象

开始升级

level 1:有用没用,先搞它出来一个

def decorator(fn):
    def inner(n):
        return fn(n) + 1
    return inner

# the "@" statement is same as f = decorator(f)
@decorator
def f(n):
    return n + 1

level 2: 使用装饰器,帅气的输出信息

def wrap_with_prints(fn):
    # This will only happen when a function decorated
    # with @wrap_with_prints is defined
    print('print this when you decorate a function')
    def wrapped():
        # This will happen each time just before
        # the decorated function is called
        print('prepare to run %s' % fn.__name__)
        # Here is where the wrapper calls the decorated function
        fn()
        # This will happen each time just after
        # the decorated function is called
        print('done running %s' % fn.__name__)

    return wrapped

@wrap_with_prints
def func_to_decorate():
    print('some be wrapped')

func_to_decorate()

level 3 : 哎呀被装饰的函数参数不一样我可怎么办呀

def log_calls(fn):
    ''' Wraps fn in a function named "inner" that writes
    the arguments and return value to logfile.log '''
    def inner(*args, **kwargs):
        # Call the function with the received arguments and
        # keyword arguments, storing the return value

        out = fn(*args, **kwargs)

        # Write a line with the function name, its
        # arguments, and its return value to the log file
        print('{} called with args {} and kwargs {}, returning {}\n'.format(fn.__name__,  args, kwargs, out))

        # Return the return value
        return out
    return inner

@log_calls
def add(a,b):
    return a+b
add(1,2)

level 4:装饰一个还不够,要装饰两次才最好

装饰器可以链式使用,但是一定要注意使用顺序

def b(fn):
    return lambda s: '<b>{}</b>'.format(fn(s))

def em(fn):
    return lambda s: '<em>{}</em>'.format(fn(s))

@b
@em
def greet(name):
    return('Hello, {}!'.format(name))

print(greet("zyt"))

level 5:装饰器也想要个属于人家自己的小参数嘛~

def add_log_out(log_level):
    def wrapper(f):
        def return_f(*real_para):
            """inner doc
            """
            print("[{}]: {} with parameter {}".format(log_level, f.__name__, real_para))
            return f(*real_para)

        return return_f
    return wrapper

# same as "add = add_log_out("INFO")(add)"
@add_log_out("INFO")
def add(a,b):
    """return a + b
    """
    return a+b

print(add(1,2))
print(add.__name__)
print(add.__doc__)

level 6:男人有了钱会变坏,函数有了装饰器却不会

from functools import wraps
def add_log_out(log_level):
    def wrapper(f):
        @wraps(f)
        def return_f(*real_para):
            """inner doc
            """
            print("[{}]: {} with parameter {}".format(log_level, f.__name__, real_para))
            return f(*real_para)

        return return_f
    return wrapper

# same as "add = add_log_out("INFO")(add)"
@add_log_out("INFO")
def add(a,b):
    """return a + b
    """
    return a+b

print(add(1,2))
print(add.__name__)
print(add.__doc__)

参考:

  1. Python Decorators Overview
  2. 简单 12 步理解 Python 装饰器
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
装饰器Python一种用于修改函数或类的行为的语法结构。它们允许在不修改原始代码的情况下,通过添加额外的功能来装饰函数或类。 装饰器实际上是一个函数,它接受一个函数作为输入,并返回一个新的函数作为输出。这个新的函数通常会在调用原始函数之前或之后执行一些额外的代码。 下面是一个简单的装饰器示例: ```python def decorator_function(original_function): def wrapper_function(): # 在调用原始函数之前执行额外的操作 print("Before the original function is called") # 调用原始函数 original_function() # 在调用原始函数之后执行额外的操作 print("After the original function is called") return wrapper_function @decorator_function def say_hello(): print("Hello!") # 调用经过装饰器修饰过的函数 say_hello() ``` 在上述示例,我们定义了一个名为`decorator_function`的装饰器函数。该装饰器接受一个名为`original_function`的函数作为参数,并返回一个新的函数`wrapper_function`。`wrapper_function`在调用原始函数之前和之后,分别打印了一些额外的信息。 通过在`say_hello`函数定义之前加上`@decorator_function`,我们将`say_hello`函数传递给了装饰器,并将装饰器返回的函数赋值给了`say_hello`。这样,当我们调用`say_hello`函数时,实际上是在调用经过装饰器修饰过的函数`wrapper_function`。 装饰器提供了一种灵活且可重复使用的方式来扩展函数的功能,比如添加日志记录、性能计时、输入验证等。在Python,还有一种更简洁的语法糖形式来使用装饰器,即使用`@`符号将装饰器应用到函数上,如上述示例的`@decorator_function`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值