Python基础0228

python中函数是一等公民,即指在程序中可无限使用的对像。

高阶函数

函数作为参数

接收一个函数A作为调用函数B的参数。并根据函数A的值,决定函数B的行为。

def sort(cmp, *args):
    ret = []
    for item in args:
        for k, v in enumerate(ret):
            if cmp(item, v):
                ret.insert(k,item) #插入永远是插到对应元素前面
                break
        else:
            ret.append(item)
    return ret

def cmp1(x,y):
    return x>=y

def cmp2(x,y):
    return x<=y

filter 过滤器

  • filter(function or None, iterable) --> filter object
  • Return an iterator yielding those items of iterable for which function(item) is true. If function is None, return the items that are true.
  • 接收一个能返回布尔类型值的函数A和一个迭代器,迭代器中的值作为函数A的参数。如果函数A返回True,filter函数将会抛出这个值;如果返回None也认为是True,并抛出值。
def biger(x):
  	return x > 5
  		
for i in filter(biger,range(10)):
  	print(i)

6
7
8
9  

any

  • any(iterable) -> bool
  • Return True if bool(x) is True for any x in the iterable. If the iterable is empty, return False.

map

  • map(func, *iterables) --> map object
  • Make an iterator that computes the function using arguments from each of the iterables. Stops when the shortest iterable is exhausted.
  • 函数的参数个数要和后面迭代器的个数相同,并以遍历完最短的迭代器作为结束。
def inc(x):
	return x + 1 

list(map(inc,[1,2,3,4]))
[2, 3, 4, 5]

def fold(fn, *args):
  	it = iter(args)    
  	ret = next(it)       # 利用生成器惰性求值,给ret赋初值,减少if判断。
  	for x in it:
      	ret = fn(ret,x)
  	return ret
  	
def add(x,y):
  	return x + y
  	
fold(add,1,2,3,4)
10

def add_sun(fn,*args):
    ret = ""
    for i in args:
        if ret:
            ret = fn(ret,i)
        else:
            ret = i    # 需要判断ret是否为空,给ret赋初值。
    return ret

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

print(add_sun(fn,1,2,3,4))
10

函数作为返回值

def fun_1(x,y):
    return x * y

def fun(x):
    def inner_fun(y):
        return x * y
    return inner_fun

fun(2)(3)=fun_1(2,3)
# 柯里化 

def biger(x):
   	def biger_fun(y):
       	return y > x
   	return biger_fun

list(filter(biger(2),range(10)))
[3, 4, 5, 6, 7, 8, 9] 

可以根据给定外层函数的参数决定内层函数的行为。

partial

  • partial(func, *args, **keywords) - new function with partial application of the given arguments and keywords.
  • 构造一个和原来函数功能相同的新函数,减少参数数量,方便后续调用。
from functools import partial

def many_args(a,b,c,x,y,z):
	print('a is {0}'.format(a))
	print('b is {0}'.format(b))
	print('c is {0}'.format(c))
	print('x is {0}'.format(x))
	print('y is {0}'.format(y))
	print('z is {0}'.format(z))

callable(partial(many_args,x=1,y=2,z=3))
True
# 定义关键字参数只能从后向前,默认按位置参数匹配
partial(many_args,x=1,y=2,z=3)(4,5,6)
a is 4
b is 5
c is 6
x is 1
y is 2
z is 3

装饰器

import time
def timeit(fn):
   	def warp(*args,**kwargs):
       	start = time.time()
       	fn(*args,**kwargs)
       	print(time.time() - start)
   	return warp

def sleep(x):
   	time.sleep(x)
   
timeit(sleep)(3)
3.0032060146331787
timeit(timeit(sleep))(3)
3.003615140914917
3.0036818981170654

@timeit
def sleep(x):
   	time.sleep(x)

sleep(3)
3.001384973526001

装饰器的本质就是一个函数,这个函数接受一个函数作为参数,但会返回一个函数,通常,返回的这个函数,是对传入的函数执行前后增加了一些语句,所以叫做装饰器。

带参数的装饰器

import time
def timeit(process_time=False):
	cacl = time.clock if process_time else time.time
   	def inner_fun(fn):
		def wrap(*args,**kwargs):
			start = cacl()
			fn(*args,**kwargs)
			print(cacl() - start)
		return wrap
	return inner_fun

def sleep(x):
	time.sleep(x)

timeit()(sleep)(3)
3.0026581287384033

timeit(True)(sleep)(3)
0.0

@timeit(False)
def sleep(x):
   	time.sleep(x)
sleep(3)
3.0025463104248047

def make_time():
   	def timeit():
   	    def inner_time(fn):
   	        def wrap(*args,**kwargs):
   	            return fn(*args,**kwargs)
   	        return wrap
   	    return inner_time
   	return timeit

fun_1 = make_time()
type(fun_1)
function

fun_1()
<function __main__.make_time.<locals>.timeit.<locals>.inner_time>

@fun_1()
def fun_2(x):
   	print(x)

fun_2(3)
3

携带参数的装饰器,就是多一层包装,外层函数根据参数决定返回的内层函数(装饰器)的行为。

装饰器外层函数对内层函数限定,确认内层函数执行的环境和条件

装饰器对函数内置参数的传递

默认不传递

借助工具传递

@wraps(fn) 相当于将被装饰的函数 fn 的属性赋值给装饰器 wrap

匿名函数

lambda

for i in filter(lambda x:x>3,[1,2,3,8,2]):
	print(i)
8

lambda x,y:x >= y(1,2)
<function __main__.<lambda>>   # 匿名函数不能接受参数直接运行

test = lambda x,y:x >= y
test(1,2)
False
posted @ 2016-02-28 00:50  蓝色骨头  阅读(262)  评论(0)    收藏  举报