随笔 - 1762  文章 - 0  评论 - 109  阅读 - 431万

python再议装饰器

装饰器实质还是一个函数,是对其他函数进行装饰的函数。装饰器函数接受被装饰函数的函数名,返回被装饰函数的函数名。对一个函数进行装饰有两个原则:一是不能修改被装饰函数的源代码;二是被装饰函数的调用方式不可以发生改变。

 

复制代码
#用dec()函数对poem()函数进行装饰,但是调用方式由poem()变成了name(),
#调用方式发生了改变...这违反写装饰器的第二个原则。解决办法:把name=
#deco(poem)这一句的name改成poem.即:name=deco(name),见下一段代码。
def deco(func): #接收一个函数名,返回相同的函数名
    print('古诗欣赏') #添加装饰语句
    return func
def poem():
    print('月落乌啼霜满天,江枫渔火对愁眠。')
name = deco(poem) #传进去函数名poem,再把返回的函数名poem赋给name
name() #装饰之后,再调用被装饰函数
'''
古诗欣赏
月落乌啼霜满天,江枫渔火对愁眠。
'''
View Code
复制代码

 

 

复制代码
#用dec()函数对poem()函数进行装饰,但是调用方式由poem()变成了name(),
#调用方式发生了改变...这违反写装饰器的第二个原则。解决办法:把name=
#deco(poem)这一句的name改成poem.即:name=deco(name),见下一段代码。
def deco(func): #接收一个函数名,返回相同的函数名
    print('古诗欣赏') #添加装饰语句
    return func
def poem():
    print('月落乌啼霜满天,江枫渔火对愁眠。')
poem = deco(poem) #传进去函数名poem,再把返回的函数名poem赋给name
poem() #装饰之后,再调用被装饰函数
'''
古诗欣赏
月落乌啼霜满天,江枫渔火对愁眠。
'''
View Code
复制代码

 

 

写带有@的装饰语句 :

复制代码
def deco(func): #接收一个函数名,返回相同的函数名
    print('古诗欣赏') #装饰语句
    return func
@deco #在被装饰的函数的头顶写装饰语句,相当于poem = deco(poem)
def poem():
    print('月落乌啼霜满天,江枫渔火对愁眠。')
#poem = deco(poem) #传进去函数名poem,再把返回的函数名poem赋给name
poem() #装饰之后,再调用被装饰函数
'''
古诗欣赏
月落乌啼霜满天,江枫渔火对愁眠。
'''
View Code
复制代码

 

一般要把装饰器写成嵌套函数:

复制代码
#对无参数的函数进行装饰
def guess_win(func): #传进去一个函数名german_team,返回一个函数名rooftop_status
    def rooftop_status():
        result = func() #相当于result=german_team()
        print('天台已满,请排队!')
        return result  #处理被装饰的函数german_team(),然后返回处理后的结果
    return rooftop_status #执行完这句后,把新定义的函数名rooftop_status返回给german_team:
                          #german_team=rooftop_status
@guess_win #这句话相当于german_team=guess_win(gernam_team)
def german_team():
    print('德国必胜!')
    return '赢了会所嫩模!输了下海干活!'
x = german_team() #由于return rooftop_status的作用是:german_team=rooftop_status
print(x)
'''
德国必胜!
天台已满,请排队!
赢了会所嫩模!输了下海干活!
'''
View Code
复制代码

 

复制代码
#对带参数的函数进行装饰
def guess_win(func): #传进去一个函数名german_team,返回一个函数名rooftop_status
    def rooftop_status(*args, **kwargs):
        result = func(*args, **kwargs)
        print('天台已满,请排队!')
        return result
    return rooftop_status #执行完这句后,把新定义的函数名rooftop_status返回给german_team:
                          #german_team=rooftop_status
@guess_win #这句话相当于german_team=guess_win(gernam_team),调用guess_win()函数
def german_team(arg):
    print('%s必胜!'% arg)
    return '德国赢了会所嫩模!输了下海干活!'
@guess_win #这句话相当于spain_team=guess_win(spain_team),调用guess_win()函数
def spain_team(arg):
    print('%s必胜!'% arg)
    return '西班牙赢了会所嫩模!输了下海干活!'
x = german_team('德国')
y = spain_team('西班牙')
print(x)
print(y)
'''
德国必胜!
天台已满,请排队!
西班牙必胜!
天台已满,请排队!
德国赢了会所嫩模!输了下海干活!
西班牙赢了会所嫩模!输了下海干活!
'''
View Code
复制代码

 

复制代码
def decorator(F):
    def new_F(a, b):
        print("input", a, b)
        return F(a, b)
    return new_F
@decorator #相当于:square_sum=decorator(square_sum)
def square_sum(a, b):
    return a**2 + b**2
@decorator
def square_diff(a, b):
    return a**2 - b**2

print(square_sum(4, 3))#相当于:
# square_sum = decorator(square_sum)
# square_sum(3, 4)
print(square_diff(4, 3))
'''
input 4 3
25
input 4 3
7
'''
View Code
复制代码

 

posted on   一杯明月  阅读(200)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示