python模型lgbm调优工具_Python装饰器的一点解读

版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖。如要转贴,必须注明原文网址

http://www.cnblogs.com/Colin-Cai/p/12977127.html

作者:窗户

QQ/微信:6679072

E-mail:6679072@qq.com

理论上,函数是一等公民(first class function)的语言都可以使用函数式编程,从而利用算子(高阶函数)来做装饰器。

装饰器一般是这样一个算子,它接受一个函数作为参数,返回另外一个函数。装饰器,顾名思义,就是把一个函数“装饰”一下,得到另外一个函数。为何要装饰一下呢?目的一般是可能设计上需要对函数做一些改装,比如原函数输出结果需要再加工加工,或者原函数的输入参数传入不一样,或者两者兼有之,等等。

迭代是编程中常用的手段,它的计算方式表现为状态的不断变换,且状态的变换具有唯一性。

比如我们使用Scheme来表示迭代。

;stat代表当前状态,next代表状态改变函数,final?代表判断状态是否终止

(define (iterate-orgin stat next final?)

(if (final?stat)

stat

(iterate-orgin (next stat) next final?)))

;将next函数和final?函数封成一个函数

(define (iterate stat f-stat)

(iterate-orgin stat (f-stat 'next) (f-stat'final)))

;最终我们需要的迭代函数

(define (it f-stat)

(lambda (stat) (iterate stat f-stat)))

以上构造出一个算子it,就是用来“装饰”迭代的函数。

我们构造一个对list求和的迭代:

可以每次把list的前面两个相加,比如对(1 2 3 4 5)求和,经过以下状态:

(1 2 3 4 5)

(3 3 4 5)

(6 4 5)

(10 5)

(15)

15

得到最后结果15。

代码可以如下:

(define (make-sum-func sym)

(if (eq? sym 'next);next函数

(lambda (lst)

(if (pair?lst)

(if (null?(cdr lst))

(car lst)

(cons (+(car lst) (cadr lst)) (cddr lst)))

lst))

(if (eq? sym 'final?);final?函数

(lambda (lst) (not (pair?lst)))'())))

然后测试一下((it make-sum-func) '(1 2 3 4 5)),得到最后结果15。

上面两个函数写在一起,我们还可以再分离一下。

;定义一个打包函数

(define (wrap-next-final next final?)

(lambda (sym)

(if (eq? sym 'next)

next

(if (eq? sym 'final?)

final?

'()))))

;下面next和final?两个函数可以分开写

(define make-sum-next

(lambda (lst)

(if (pair?lst)

(if (null?(cdr lst))

(car lst)

(cons (+(car lst) (cadr lst)) (cddr lst)))

lst)))

(define make-sum-final?(lambda (lst) (not (pair?lst))))

;于是函数就可以下面这样表示

(define make-sum-func (wrap-next-final make-sum-next make-sum-final?))

总而言之,装饰器就是这样一类算子。

Python也是这样,只是Python提供了@这样的语法,实际上是个语法糖,与其说是简写,倒是更像是个语法提醒这是一个装饰器。

我们这次希望来显示一下mysym,还是用求和。

先写一个简单的mysum函数用于求和:

def mysum(*args):

ret=0for i inargs:

ret+=ireturn ret

做一个算子,来扩充它的输入参数:

这里需要用来判断一个对象是否是可迭代对象,

from collections import Iterable

然后,如果判断对象x是否是可迭代对象,只需要:

isinstance(x, Iterable)

算子如下:

from collections importIterabledefargs_expan(f):def f2(*args):

lst=[]for i inargs:ifisinstance(i, Iterable):

lst.append(f(*i))else:

lst.append(i)return f(*lst)return f2

然后在mysum前添加装饰器标志

@args_expandef mysum(*args):

ret=0for i inargs:

ret+=ireturn ret

测试如下:

print(mysum(1,2,3,4,5))print(mysum((1,2,3,4,5)))print(mysum([1,2,3,4,5]))print(mysum(range(1,6)))print(mysum(map(lambda x:x+1, range(5))))print(mysum(filter(lambda x:x<6, range(10))))#构造了一个生成器

defgen_range(a, b):while a

a+= 1

print(mysum(\

filter(lambda x:x<6, range(10)), \6, \

[7,8], \

(9, 10), \

map(lambda x:x+11, range(10)), \

gen_range(21,101)))

运行得到:

15

15

15

15

15

15

5050

终于看到,函数功能已被扩充。

这个装饰器还可以装饰别的函数,比如乘积、统计等。

从而,装饰器就是这样一个算子,一般用来改造函数的输入或输出,避免重复写代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值