Python装饰器

理解装饰器

装饰器就是在不修改源代码和调用方式的基础上给其增加新的功能,并且多个装饰器可以装饰在同一个函数上。
我们可以一步一步构建一个模型来理解装饰器。
我们现在有一个函数,我们称其为1#函数,现在我们要实现装饰器所提到的功能,即不改变源代码并增加新的功能。虽然我们现在没有思路,但是我们可以先把新的功能函数写出来,我们称其为2#函数。现在功能上的问题解决了,我们需要把两个函数合并,既然不能动1#,那我们只能把1#合并到2#下面,也就是当执行2#时既会执行2#,也会顺便执行1#;并且因为不能改变调用方式,我们需要之前执行1#的命令现在去执行2#。解决这两个问题,我们的装饰器就完成了。在思考时,我们可以把问题写在纸上。

  • 原本执行1#的命令要去执行2#
  • 在执行2#的同时执行1#

实现装饰器

1#函数

def hello():
    print('hello')

2#函数

def world():
    print('world')

最终符合要求的结果(大家最好不要像我这样用脚起名)

def hello():
    print('hello')
def world(func):
    def helloworld():
        func()
        print('world')
    return helloworld
hello = world(hello)
hello()

我们可以看到原函数并无改变,执行函数的命令也没有改变,满足了要求,那么问题是怎样解决的

解决第一个问题

def hello():
    print('hello')
def world(func):
    def helloworld():
        func()
        print('world')
    return helloworld
print(hello)
hello = world(hello)
print(hello)
<function hello at 0x00000169CF612E18>
<function world.<locals>.helloworld at 0x00000169D12E8B70>

我们看到函数hello发生了变化,此时执行hello()已经不再是执行hello函数,而是执行了helloworld函数。
我们比较一下

hello()
world(hello())

这两个命令在这里的作用是一样的

解决第二个问题

既然我们转而去执行helloworld函数了,那么我们来看看helloworld函数是怎么样的

def world(func):
    def helloworld():
        func()
        print('world')
    return helloworld

这里的func就是hello,也就是说,2#函数变成了这样:

def world(hello):
	def helloworld():
		hello()
		print('world')
	return helloworld		

此时我们成功实现了使2#函数执行同时把1#函数也执行一遍。

装饰器封装

def world(func):
    def helloworld():
        func()
        print('world')
    return helloworld
@world
def hello():
    print('hello')
hello()

我们一般会将装饰器写成这种格式。也就是说,当看到@……的时候,省略号代表装饰器,而下面的内容是源函数。

当源函数携带变量

如果源函数变成了这样呢

def hello(name):
    print('hello %s'%name)
hello('world')

当你理解了之前解决的第二个问题之后,这根本是迎刃而解

def world(func):
    def helloworld(name):
        func(name)
        print('world')
    return helloworld
@world

def hello(name):
    print('hello %s'%name)
hello('world')

写在最后

很多Python初学者一到装饰器就懵逼,如果只看概念可能确实难以理解,这个时候的学习就应该换种思路,不去想它为什么要这么做,而是想正常情况下我们应该怎么做,当从一头向另一头推导很困难的时候,就换一个方向。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值