浅谈python装饰器

装饰器是什么?

以前并没有怎么注意装饰器,只是用现成的,最近发现,在一些特定的可复用场景下,装饰器的确起到了不小的作用,并且可以大大简化我们的代码。

装饰器的概念

谈到装饰器,就一定离不闭包。那么什么是闭包呢?

闭包

闭包就是能够读取其他函数内部变量的函数。通俗理解可以就是一个高级嵌套的函数。
闭包还有一个概念很重要,那就是作用域!闭包是指可以访问其所在作用域的函数。
我们来看看下面的例子:

def A():
     a = 1
     def B():
          print(a)
     return B

你在函数A中定义了函数B,并将B作为A的返回值返回,B中又使用了A中定义的变量,此时就形成了闭包。是不是很拗口?
基本可以通过你中有我我中有你来概括,但又感觉好像有点不对。后来在网上看到一个很有趣的比喻:就是别人家有某个东西,你想拿到但是因为权限不够(不打死你才怪),但是你可以跟家里的孩子关系好,可以通过他拿到!
这个家就是局部作用域,外部无法访问内部变量,孩子是返回对象,对家里的东西有访问权限,借助返回对象间接访问内部变量!
了解了闭包,那么装饰器就比较好理解了,装饰器其实就是一个特殊的集成的闭包。

装饰器的作用

为什么要用装饰器

先来举个例子

import time
def work():
	time1 = time.time()
	print(f'任务开始,开始时间:{str(time1)}')
	do something
	print(f'任务结束,耗时:{str(time.time()-time1)}S')
	

以上是最为常见的一个日志打印。这是在只有一个任务的时候,这样做没什么问题。但是在一个项目中,少则几十多则上千的任务、方法、接口需要打印日志,难道每个都这样写吗?假如我要修改其中一个多加一个打印或者修改一下输出逻辑,还需要每个都修改吗?这时候就轮到我们的主角装饰器登场了

装饰器的简单使用

首先,我们先来定义一个装饰器

import time
def work_log(func):
	def log_time():
		time1 = time.time()
		print(f'任务开始,开始时间:{str(time1)}')
		func()
		print(f'任务结束,耗时:{str(time.time()-time1)}S')
	return log_time

如此一来,一个简单的装饰器就完成了,下面看下怎么使用吧

@work_log
def work():
	do something

这时,在调用work方法的时候,会输出响应的日志开始和结束时间的打印

中级装饰器

函数千千万,在实际场景中,大多数函数都带有餐数,还有一些类方法
带参数的又如何使用呢?还是拿打印时间日志来距离

import time
def work_log(func):
	def log_time(*args, **kwargs):
		time1 = time.time()
		print(f'任务开始,开始时间:{str(time1)}')
		func(*args, **kwargs)
		print(f'任务结束,耗时:{str(time.time()-time1)}S')
	return log_time

在这里还得感叹一下,python里的*args, **kwargs还真是简便,这样一来,带装饰器的函数,不管加了什么参数都可以应对
装饰器的用法一样

@work_log
def work(todo1, todo2):
	print(todo1)
	do something
	print(todo2)

带参数的装饰器

在一些场景中,不管调用的函数有参数,装饰器本身也可以带不同的参数来控制变量(虽然目前我还没遇到过需要我这样做的场景,不过这里就先举个栗子吧)

import time
def logger(level):
	def work_log(func):
		def log_time(*args, **kwargs):
			time1 = time.time()
			print(f'{level}:任务开始,开始时间:{str(time1)}')
			func(*args, **kwargs)
			print(f'{level}:任务结束,耗时:{str(time.time()-time1)}S')
		return log_time
	return work_log

如此一来,就可以在调用@logger的时候输入增加日志级别的参数,比如这样:

@work_log(INFO)
def work(todo1, todo2):
	print(todo1)
	do something
	print(todo2)

是不是挺简单?
人生苦短,我用python

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值