Python 修饰符 @ 的用法汇总

为已经存在的函数A,添加新的功能B

一、Python 修饰符 @

1.1 例子:为函数 Fun_A 添加 Fun_B 的新功能

def Func_A(f):
    f() # 在这里添加新功能
    print("Func_A is running")
    f() # 在这里也添加新功能
    return

@Func_A # 调用 Func_A 并加入新功能
def Func_B(): # 新功能 Func_B 的定义
    print("Func_B is running")
    return

运行结果:

Func_B is running
Func_A is running
Func_B is running

1.2 复杂一点的例子:嵌套

def Func_1(f):
    f()
    print("Func_1 is running")
    return


def Func_2(f):
    print("Func_2 is running")
    f()
    return


@Func_1
def Func_3():
    print("Func_3 is running")
    @Func_2
    def Func_4():
        print("Func_4 is running")

运行结果:

Func_3 is running
Func_2 is running
Func_4 is running
Func_1 is running

1.3 更复杂的例子:带有参数

def Func_A(f):
    f("111") # 在这里添加带有参数新功能
    print("Func_A is running")
    f("222") # 在这里也添加带有参数新功能
    return

@Func_A # 调用 Func_A 并加入新功能
def Func_B(s): # 新功能 Func_B 的定义
    print(s+"Func_B is running")
    return

运行结果:

111Func_B is running
Func_A is running
222Func_B is running

1.4 再复杂一点的例子:返回一个函数

def log(func):
    def wrapper():
        print('log开始 ...')
        func("uuu")
        print('log结束 ...')

    return wrapper # 运行后会返回一个函数


@log # 用新的方法修饰 log 并运行
def test1(s):
    print(s+'test1 ..')

@log
def test2(s):
    print(s+'test2 ..')

print(log.__name__) # 即显示原函数的名字
print(test1.__name__) # 显示返回来的函数的名字,即 wrapper
print(test2.__name__) # 显示返回来的函数的名字,即 wrapper
print('\n')
test1() # 由于返回了一个函数,即可以直接运行
print('\n')
test2() # 由于返回了一个函数,即可以直接运行

运行结果:

log
wrapper
wrapper


log开始 ...
uuutest1 ..
log结束 ...


log开始 ...
uuutest2 ..
log结束 ...

二、functools 模块中修改函数属性的方法 @wraps

前面的例子中看到,用 @ 修饰符添加新功能,返回一个函数,那新功能的函数名称发生变化

这个变化我们希望避免

于是可以用 functools 模块中修改函数属性的方法 @wraps

2.1 保留新功能的函数名

from functools import wraps


def log(func):
    @wraps(func)
    def wrapper():
        print('log开始 ...')
        func()
        print('log结束 ...')

    return wrapper


@log
def test1():
    print('test1 ..')

@log
def test2():
    print('test2 ..')


print(test1.__name__)
print(test2.__name__)
print('\n')
test1()
print('\n')
test2()

运行结果:

test1
test2


log开始 ...
test1 ..
log结束 ...


log开始 ...
test2 ..
log结束 ...

2.2 新增功能带有多个参数

from functools import wraps

def log(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print('log开始 ...', func.__name__)
        ret = func(*args, **kwargs)
        print('log结束 ...')
        return ret

    return wrapper

@log
def test1(s):
    print('test1 ..', s)
    return s

@log
def test2(s1, s2):
    print('test2 ..', s1, s2)
    return s1 + s2

# 首先这里用修饰符添加新功能后,返回的是一个函数
# 这个函数的作用在于:
# 1、打印 'log开始 ...',打印函数名(通用功能)
# 2、运行函数特有功能,返回一个值
# 3、打印 'log结束 ...'(通用功能)
# 4、返回之前的值

answer_1 = test1('a') # 这里直接运行了返回的函数 wrapper
print("\n")
answer_2 = test2('a', 'bc') # 这里直接运行了返回的函数 wrapper
print("\n")


print(answer_1) # 打印返回值
print(answer_2) # 打印返回值

运行结果:

log开始 ... test1
test1 .. a
log结束 ...


log开始 ... test2
test2 .. a bc
log结束 ...


a
abc

2.3 修饰符带有参数

from functools import wraps

def log(arg):
    def _log(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            print('log开始 ...', func.__name__, arg)
            ret = func(*args, **kwargs)
            print('log结束 ...')
            return ret

        return wrapper

    return _log


@log('module1')
def test1(s):
    print('test1 ..', s)
    return s


@log('module2')
def test2(s1, s2):
    print('test2 ..', s1, s2)
    return s1 + s2




answer_1 = test1('a')
print("\n")
answer_2 = test2('a', 'bc')
print("\n")


print(answer_1)
print(answer_2)

运行结果:

log开始 ... test1 module1
test1 .. a
log结束 ...


log开始 ... test2 module2
test2 .. a bc
log结束 ...


a
abc
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
修饰符(decorators)是Python中的一种特殊语法,用于修改函数或类的行为。它们是通过在函数或类定义之前使用@符号,后跟修饰符函数或类的方式来实现的。 修饰符函数接受被修饰的函数作为参数,并返回一个新的函数或修改原始函数。这样,当调用被修饰的函数时,实际上会执行修饰后的函数。 修饰符主要用于以下几个方面: 1. 扩展函数的功能:可以在不修改原始函数代码的情况下,通过添加修饰符来增加额外的功能。 2. 函数注册:可以使用修饰符将函数注册到某个中心,以便在其他地方使用。 3. 访问控制:可以使用修饰符来限制对某些函数或类的访问权限。 下面是一个简单的示例,演示如何使用修饰符来记录函数的执行时间: ```python import time def timeit(func): def wrapper(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) end_time = time.time() execution_time = end_time - start_time print(f"函数 {func.__name__} 的执行时间为 {execution_time} 秒") return result return wrapper @timeit def my_function(): # 函数的具体实现 time.sleep(1) my_function() ``` 在上面的例子中,`timeit` 是一个修饰符函数,它接受被修饰的函数作为参数,并返回一个新的函数 `wrapper`。`wrapper` 函数记录了被修饰函数的执行时间,并在执行结束后打印出来。通过在 `my_function` 函数定义之前使用 `@timeit` 修饰符,`my_function` 函数就会被修饰并添加了计时功能。 希望这个例子能帮助你理解修饰符的概念和用法。如果还有其他问题,请随时提问!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值