天天看点

python函数装饰器python 函数装饰器

注:读本文章前请先了解闭包或者读作者的python闭包附上链接python闭包

python 函数装饰器

函数装饰器 decorators

  • 定义:在不改变原函数的调用以及内部代码的情况下,为其添加新功能的函数.
  • 语法:
    def 函数装饰器名称(func):
      		def 内嵌函数(*args,**kwargs)
      			需要添加的新功能
      			return func(*args, **kwargs)
      		return wrapper
      	
      	@ 函数装饰器名称
      	def 原函数名称(参数):
      		函数体
      	原函数(参数)
               
  • 本质: 使用“@函数装饰器名称”修饰原函数,等同于创建与原函数名称相同的变量,关联内嵌函数;故调用原函数时执行内嵌函数。

    原函数名称 = 函数装饰器名称(原函数名称)

  • 装饰器链:

    一个函数可以被多个装饰器修饰,执行顺序为从近到远。

函数装饰器的应用 :

需求:在两个方法实现的功能基础上,增加新功能(打印方法名称)

def say_hello():
    print("hello")


def say_goodbye():
    print("goodbye")


say_hello()
say_goodbye()
# 输出
'''
hello
goodbye
'''
           

方案1

缺点:代码重复.

解决:提取打印方法名称的功能

def say_hello():
    print(say_hello.__name__)
    print("hello")


def say_goodbye():
    print(say_goodbye.__name__)
    print("goodbye")


say_hello()
say_goodbye()
# 输出
'''
say_hello
hello
say_goodbye
goodbye
'''

           

方案2

缺点:在两个已有功能的内部,增加新功能,代码可读性差.

def print_func_name(func):
    print(func.__name__)


def say_hello():
    # print(say_hello.__name__)
    print_func_name(say_hello)
    print("hello")


def say_goodbye():
    # print(say_goodbye.__name__)
    print_func_name(say_goodbye)
    print("goodbye")


say_hello()
say_goodbye()
# 输出:
'''
say_hello
hello
say_goodbye
goodbye
'''
           

方案示例(略…上正题)

使用函数装饰器

包装器适应所有的旧功能参数

定义者负责包装函数,调用者只负责调用

# 定义函数装饰器
def print_func_name(func):
    # 包装新旧功能
    def wrapper(*args, **kwargs):
        # 增加的新功能
        print(func.__name__)
        # 旧功能
        return func(*args, **kwargs)

    return wrapper  # 返回包装器
# 使用函数装饰器    
@print_func_name    # say_hello = print_func_name(say_hello)
def say_hello(name):
    print(name, "hello")
    return "哈哈"


@print_func_name
def say_goodbye(name, age):
    print(age, name, "goodbye")

# # ---------以上是定义者--以下是调用者-----------------
print(say_hello("灭霸"))
say_goodbye("北极星女孩", 25)

# 输出:
'''
say_hello
灭霸 hello
哈哈
say_goodbye
25 北极星女孩 goodbye
'''