python装饰器

python装饰器

举例一个加法函数,想要增强它的功能,能够输出被调用过,以及调用的参数信息
def add(x,y):
	return x+y

#增强信息输出功能

def add(x,y):
	print("call add,x+y"") #输出到控制台
	return x+y
	

上面加法函数虽然实现了需求但是打印语句耦合性太高,加法函数属于业务功能,而输出信息的功能非业务功能代码放到一起不好

为了做到业务分离,如下可以实现原函数的增强


def add(x,y):
	return x+y

def logger(fn,x,y):
	print("start")
	x=fn(x,y)
	print("end")
	return x

print(logger(add,4,5))

#但是这种不够灵活

def add1(x,y,z):
	return x+y+z
	
def add2(x,y,*args,z):
	pass
	
#再有上面这样的函数参数就不能通用 改造

def logger(fn,*args,**kwargs):  #*args(元组),**kwargs(字典)   可变形参 *args 顺序参数组成的元组 **kwargs keyword形式
	print("start")
	x=fn(*args,**kwargs)    #解构赋值
	print("end")
	return x

但是这种不顺眼能不能进行柯里化呢

def logger(fn):
	def_logger(*args,**kwargs):
		print("start")
		x=fn(*args,**kwargs)
		print("end")
		return x
	return  _logger

#调用 
logger(add)(4,5)

add=logger(add)
add(4,5)

由于形成了闭包传进去的函数被保留了所以这么写没有问题

#装饰器
@logger        # 自动找下一行获取函数名  add=logger(add) 
def add(x,y):
	return x+y

#@logger 相当于 add=logger(add) 这就是装饰器


文档字符串

必须放在函数第一行
def add(x,y):
	""" this is a function of addition"""  #文档字符串
	pass

带参数装饰器

上面的装饰器代码改变了add函数的名字

在这里插入图片描述

def copy_propertles(src,dst):
    dst.__name__=src.__name__
    dst.__doc__=src.__name__

def logger(fn):
    def _logger(*args,**kwargs):
        print("start")
        x=fn(*args,**kwargs)
        print("end")
        return x
    copy_propertles(fn,_logger)
    return _logger



@logger
def add(x,y):
    return x+y

这样实现了add还保有原名字

在这里插入图片描述
把这个copy函数改写成装饰器

def copy_propertles(src):
	def wrapper(dst):
	    dst.__name__=src.__name__
    	dst.__doc__=src.__name__
    	return  dst
    return wrapper
    
def logger(fn):
	@copy_propertles(fn)          #相当于 copy_propertles(fn)(_logger)  ==> wrapper(_logger)
    def _logger(*args,**kwargs):
        print("start")
        x=fn(*args,**kwargs)
        print("end")
        return x
    copy_propertles(fn,_logger)
    return _logger



@logger
def add(x,y):
    return x+y

copy_propertles函数就是一个带参装饰器
在这里插入图片描述
官方模块实现copy函数
在这里插入图片描述
add.wrapped 保留原函数

functools模块

  • partial方法偏函数,把函数部分的参数固定下来,相当于为部分参数添加一个固定的默认值,返回一个新函数,是原函数的封装
import functools
def add(x,y)->int:
	return x+y

newadd=functools.partial(add,y=5)

print(newadd(5))
print(newadd(5,y=7))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值