装饰器初探

语法糖@:

@dec
def f():
	pass
# 等价于
f = dec(f)

@dec(x)
def f():
	pass
f = dec(x)(f)

写装饰器套路

装饰器是否需要配置

def dec(f):   #装饰器函数
	do_something(f)
	def wrapper(*args ,**kwargs):
		preprocess()
		result = f(*args, **kwargs)
		postprocess()
		return result
	return wrapper
	
@dec
def f():
	pass

原函数是否需要包装

def dec_3(*opts):    #配置函数
	def dec(f):		#装饰器函数
		def wrapper(*args, **kwargs):  #包装函数
			# do something
		return f(*args, **kwargs)
	return dec

demo 可带参数,又可省略的装饰器

体会python没有重载机制,通过灵活的传参,覆盖大多数重载的需求

from functools import wraps
tasks = []

def count(f):
	counter = 0
	@wraps(f)
	def wrapper(*args, **kwargs):
		nonlocal counter
		counter += 1
		return f(*args, **kwargs) + ' '+str(counter)
	#update_wrapper(wrapper, f)
	return wrapper

def update_wrapper(wrapper, wrapped):
	setattr(wrapper, '__name__', wrapped.__name__)

#让装饰器既可以接收参数,又可以接收函数。
def task(name = ''):
	# 通过动态分析参数类型,来区分功能
	if callable(name):
		#如果没有传配置,相当于_task(f)
		return task()(name)
	def _task(f):
		global tasks
		tasks.append(f)
		if name:
			setattr(f,'name', name)
		else:
			setattr(f, 'name', f.__name__)  #封装细节
		return f
	return _task
	
@task
def play():
	return 'playing ...'
	
@task("投币")
@count
def coin():
	return "ding!"


def action():
	for task in tasks:
		print(task.name, ":", task())
	
if __name__ == '__main__':
	action();
	action();
	action();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值