`

Python中的函数、装饰器

 
阅读更多
  • map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。
>>> s = ['AASDa', 'dendY']
>>> def formatStr(ss):
return ss[0].upper() + ss[1:len(ss)].lower()
>>> v = formatStr('aaaB')
>>> v
'Aaab'
>>> map(formatStr, s)
<map object at 0x000000000320A668>
>>> for v in map(formatStr, s):
print(v)
Aasda
Dendy

  • reduce把一个函数作用在一个序列[x1, x2, x3...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
>>> L = [2, 3, 4]
>>> def prod(a, b):
return a * b
>>>
>>> from functools import *
>>> reduce(prod, L)
24
>>>
  • filter函数,方法同map,目的是过滤list中符合条件的元素:
>>> s = [1, 2, -3, -5]
>>> def notLt0(x):
return x >= 0
>>> filter(notLt0, s)
<filter object at 0x000000000320A940>
>>> for v in filter(notLt0, s):
print(v)
1
2
>>>
如上的示例,定义一个notLt0的方法,该方法用于判断元素是否大于等于0,是则返回True,否则返回False。而filter则会将列表s的每一个元素作为参数调用notLt0方法,最后将所有返回True的元素重新组装成一个list返回。
  • 匿名函数:无须定义函数的名称,格式如下:
fn = lambda 函数参数列表: 函数体
其中fn为返回的匿名函数,例如:
'''
匿名函数
'''
f = lambda x : x * x
print(f(2))
  • 函数的闭包,类似javascript的闭包,即外部函数返回内部函数的引用,内部函数可能持有外部函数变量的引用,例如:
'''
闭包
'''
def count():
fs = []
for i in range(1, 4):
def f():
print(i)
return i * i
fs.append(f)
return fs
f1, f2, f3 = count()
print('before execute...')
print(f1()) # 输出:9
print(f2()) # 输出:9
print(f3()) # 输出:9
print('after execute...')
由于每次执行fn()时,i的值都变为了3,所以输出的结果并非预期的1,4,9,解决这种问题有多种方式,可以再定义一层闭包,也可以将fs中的元素修改为f函数的执行结果,而不是函数引用。
  • 装饰器(decorator),包装目标函数,在不改变原目标函数的情况下,对其进行包装,实现更多的功能。
例如:实现一个打印日志的装饰器:
'''
装饰器
'''
# 定义一个装饰器(decorator)
def log(fn):
def wrapper(*args, **kw):
print('call : %s' % (fn.__name__))
return fn(*args, **kw)
return wrapper
@log
def func():
print ('hello!')
func()
其中,log函数为一个装饰器,除了完成fn函数本身的功能外,还添加了打印日志的功能,log函数返回一个装饰函数wrapper,打印的结果:
call : func
hello!
Python中使用@符号来表示装饰器(不是java的注解,形式类似),在执行func函数时,解释器看到@符号标识,会先执行log方法,并将func函数作为参数,此时func函数依然存在,但是同名的func变量会指向wrapper函数:
print(func.__name__)
输出wrapper,同:
func = wrapper(*args, **kw):
print('call : %s' % (fn.__name__))
return fn(*args, **kw)
所以,执行func()函数其实执行的是wrapper函数。

上边为最简单的装饰器,如果我们要实现可自定义参数的装饰器呢?
# 自定义文本的装饰器
def log(text):
def decorator(fn):
def wrapper(*args, **kw):
print('log : %s, function name : %s. ' % (text, fn.__name__))
fn(*args, **kw)
return wrapper
return decorator
@log('this is a log text.')
def func():
print ('hello!')
func()
print(func.__name__) # 输出:wrapper
如上,我们需要再定义一个函数decorator来接收我们定义的参数信息,除了上边的执行过程外,在调用func函数时,解释器会先执行log和decorator函数,最后在执行wrapper函数,形式如下:
func = log(自定义参数)(func)
  • 偏函数,functools.partial,固定函数参数,形成新的函数:
如果我们需要在转换为int的时候确定进制,Python提供了int方法:
int(x, base = 10)
base为此时x的进制数,默认为10,我们写一个将二进制字符串转换为int的方法:
def int2(x):
return int(x, base = 2)
s = int2('110')
print (s) # 输出6
但是,其实Python已经为我们做了这样的事情,那就是利用functools.partial的方法:
int2 = functools.partial(int, base = 2)
s = int2('110')
print (s) # 输出6
当然,该函数用法有很多,例如将max函数默认与一些元素比较:
max2 = functools.partial(max, 10, 20, 30)
s = max2(1, 2, 3, 40)
print(s) # 输出:40
s = max2(1, 2, 3)
print(s) # 输出:30
这样,max函数在比较的元素中,默认会加入10,20,30了。





分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics