python 装饰器在类中使用的工作原理

本文介绍了装饰器在软件开发中的重要性,尤其是在处理代码改写和功能扩展时。通过装饰器,可以在保持原有代码稳定性的前提下,增强代码的可读性和可维护性,实现灵活的代码扩展,从而提高开发效率和代码质量。
摘要由CSDN通过智能技术生成

装饰器是一个非常关键的概念,它在软件开发中频繁地被使用。特别是在我们接手旧的项目,需要对原有的方法进行改写或扩展功能时,装饰器就显得尤为重要。通过使用装饰器,我们可以在不改变原有代码的基础上,对方法进行“装饰”或“加工”,添加新的功能或修改行为。这种方式不仅保证了原代码的完整性和稳定性,同时也提高了代码的可读性和可维护性。通过装饰器,我们可以更加灵活地对代码进行扩展和修改,使其更好地适应新的需求或业务场景。因此,熟练掌握装饰器的使用,对于提高开发效率和代码质量具有重要意义。

简单的示例:

print("第一步")
class MyClass: # 定义一个类,其中的方法使用装饰器
    print("第二步")
    def __init__(self):
        print('MyClass初始化')
    # 定义一个简单的装饰器函数
    def newfunc(origin):
        print("第三步")
        def wrapper(*args, **kwargs):
            print("fun函数执行前操作")
            result = origin(*args, **kwargs)  # 调用原函数
            print('fun执行后操作')
            kaifang = result+result
            return kaifang
        print("第四步")
        print('内存地址-->',origin)
        return wrapper
    @newfunc  # 应用装饰器到函数
    def fun1(self, num):
        print(f"执行fun1函数,输入参数为{num}")
        return num
    @newfunc
    def fun2(self, str):
        print(f"执行fun2函数,输入参数为{str}")
        return str+'C'
obj = MyClass()
message = obj.fun1(5)#
print(message)
message = obj.fun2('ab')
print(message)

执行结果
在这里插入图片描述
当执行程序,还没有 实例化obj = MyClass() 就会先执行
代码执行过程如下:
1.print(“第一步”) 执行,输出“第一步”。
2.开始定义MyClass类。
3.print(“第二步”) 在类定义体内部但不在任何方法或函数内部,因此会立即执行,输出“第二步”。
4.类的__init__方法定义完成,但此时并未调用,所以不会执行其中的print(‘MyClass初始化’)。
5.newfunc定义完成,但此时并未应用到任何方法上,所以不会执行装饰器内部的wrapper函数。
6.使用@newfunc装饰器装饰fun1方法。这会将fun1方法作为参数传递给newfunc装饰器,然后newfunc返回一个新的函数wrapper,这个函数会替换原来的fun1方法。此时会执行装饰器内部的print(“第三步”)和print(“第四步”),输出“第三步”和“第四步”。接着,print(‘内存地址–>’,origin)会输出fun1方法的内存地址。
7.使用@newfunc装饰器装饰fun2方法,过程与装饰fun1相同。
8.实例化MyClass类,创建对象obj。此时会调用__init__方法,执行print(‘MyClass初始化’),输出“MyClass初始化”。
9.调用obj.fun1(5)。由于fun1已经被装饰器替换为wrapper函数,所以会先执行wrapper函数内部的print(“fun函数执行前操作”),输出“fun函数执行前操作”。接着调用原来的fun1方法,执行print(f"执行fun1函数,输入参数为{num}"),输出“执行fun1函数,输入参数为5”。fun1方法返回5,然后wrapper函数计算kaifang = result+result,即kaifang = 5+5,得到10,最后返回10。
print(message)输出fun1的返回值,即10。
这里肯定有人会问:为什么 message = obj.fun1(5) 不执行print(“第三步”)和print(“第四步”)

*在调用 obj.fun1(5) 的时候,print(“第三步”) 和 print(“第四步”) 并未执行的原因是因为它们都在装饰器函数 newfunc 内部定义的,而在调用 obj.fun1(5) 时,装饰器函数 newfunc 已经在 fun1 方法上被应用,所以再次定义 newfunc 并不会触发其内部的 print 语句。
具体来说:
当 Python 解释器执行 MyClass 类的定义时,其中的方法并没有被调用。因此,newfunc 装饰器函数也没有被调用,因此其中的 print(“第三步”) 和 print(“第四步”) 语句也没有被执行。
当你调用 obj.fun1(5) 时,实际上是调用了被装饰后的 fun1 方法,而不是直接调用原始的 fun1 方法。

所以,即使装饰器函数 newfunc 在 fun1 方法中被调用,但它在 MyClass 类的定义阶段已经被应用到 fun1 方法上了,所以不会再触发内部的 print 语句。*

10.调用obj.fun2(‘ab’)。过程与调用fun1相同,先执行wrapper函数内部的“fun函数执行前操作”,然后调用原来的fun2方法,输出“执行fun2函数,输入参数为ab”。fun2方法返回’abC’,然后wrapper函数计算kaifang = result+result,即kaifang = ‘abC’+‘abC’,得到’abCabC’。
print(message)输出fun2的返回值,即’abCabC’。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值