python高阶函数、柯里化、装饰器、参数注解

匿名 (未验证) 提交于 2019-12-02 22:51:30

一、高阶函数

举例:         def counter(base):         def inc(step=1)             base += step             return base         return inc


1、自定义sort函数

  • 仿照内建函数sorted,自行实现一个sort函数(不使用内建函数),能够为列表元素排序
  • 内建函数sorted函数是返回一个新的列表,可以设置升序或者降序,可以设置一个排序的函数
  • sorted函数的实现原理,扩展到map,filter函数的实现原理
方式一:         def sort(iterable,reverse=False):             ret = []             for x in iterable:                 for i,y in enumerate(ret):                     flag = x>y if reverse else x<y                     if flag:   #找到大的就地插入                         ret.insert(i,x)                         break                 else:                     ret.append(x)             return ret         print(sort([1,3,4,52,6,10])               方式二:         def sort(iterable,fn=lambda a,b:a>b):             ret = []             for x in iterable:                 for i,y in enumerate(ret):                                          if fn(x,y):   #fn函数的返回值是bool                         ret.insert(i,x)                         break                 else:                     ret.append(x)             return ret         print(sort([1,3,4,52,6,10])

2、sorted(iterable[,key][,reverse]) 排序函数

  • 返回一个新的列表,对一个可迭代对象的所有元素排序,排序规则为key定义的函数,reverse表示排序反向
    sorted(lst,key=lambda x:6-x) 排序返回一个新列表     >>> lst = [1,3,4,52,6,10]     >>> sorted(lst,key=lambda x:6-x)     [52, 10, 6, 4, 3, 1]          list.sort(key=lambda x:6-x)  就地修改lst,没有返回一个新列表     >>> lst.sort(key=lambda x:6-x)     >>> lst     [52, 10, 6, 4, 3, 1]     >>> 

3、filter(function,iterable)

    举例:过滤出数列中能被3整除的数字         >>> lst = filter(lambda x:x%3==0,[1,9,55,150,-3,78,28,123])         >>> list(lst)         [9, 150, -3, 78, 123]         >>> 

4、map(function,*iterables) --> map object

  • 对多个可迭代对象的元素按照指定的函数进行映射,返回一个迭代器
    >>> list(map(lambda x:2*x+1,range(5)))     [1, 3, 5, 7, 9]     >>>           >>> dict(map(lambda x:(x%5,x),range(500)))     {0: 495, 1: 496, 2: 497, 3: 498, 4: 499}     >>> 


二、柯里化

    如:z = f(x,y)z转换成z = f(x)(y)的形式     将加法函数柯里化         def add(x,y):             return x + y     转换如下:         def add(x):             def_add(y)                 return x + y             return _add         add(5)(6)


三、装饰器

1、无参装饰器

        @logger  # 等价于add = logger(add)         def add(x,y):  #业务函数             return x+y                  def logger(fn):  #装饰器函数             def wrapper(*args,**kwargs):                 print('begin')                 x = fn(*args,**kwargs)                 print('end')                 return x             return wrapper         print(logger(add)(5,y=50))  等价于print(add(45,40))         


2、装饰器和高阶函数

  • 装饰器是高阶函数,但是装饰器是对传入函数的功能的装饰(功能增强)
举例:             import datatime             import time             def logger(fn):                 def wrap(*args,**kwargs):                     #befor 功能增强                     print("args={},kwargs={}".format(args,kwargs))                     start = datetime.datetime.now()                     ret = fn(*args,**kwargs)                     #after                     duration = datetime.datetime.now() - start                     print("function {} took {}s".format(fn.__name__,duration.total_seconds()))                     return ret                 return wrap                              @logger              def add(x,y):                 print('==========call add===========')                 time.sleep(2)             print(add(4,y=7))             

3、文档字符串

    举例:         >>> def add(x,y):             """This is a function addition"""             a = x+y             return x+y          >>> print("name={} doc={}".format(add.__name__,add.__doc__))         name=add doc=This is a function addition         >>> print("name={}\ndoc={}".format(add.__name__,add.__doc__))         name=add         doc=This is a function addition         >>>     


4、带参装饰器

1, 提供一个函数,被封装函数属性==copy==》包装函数属性,改造成带参装饰器     def copy_properties(src):     def _copy(dst):         dst.__name__ = src.__name__         dsr.__doc__ = src.__doc__         return dst     return _copy      def logger(fn):         @copy_properties(fn)  # wrapper = wrapper(fn)(wrapper)         def wrapper(*args,**kwargs):             'I am wrapper'             print('begin')             x = fn(*args,**kwargs)             print('end')             return x         return wrapper     @logger     def add(x,y):         '''This is a function for add'''         return x+y     print("name={},doc={}".format(add.__name__,add.__doc__))  2,  需求:获取函数的执行时长,对时长超过阈值的函数记录一下 import time  import datetime  def copy_properties(src):     def _copy(dst):         dst.__name__ = src.__name__         dst.__doc__ = src.__doc__         return dst     return _copy  def logger(duration):     def _logger(fn):         @copy_properties(fn)         def wrapper(*args,**kwargs):             start = datetime.datetime.now()             ret = fn(*args,**kwargs)             print(111,args,kwargs)             delta = (datetime.datetime.now() - start).total_seconds()             print(2222,delta,duration)  # duration阈值设置为5秒,由logger函数传入             print('so slow') if delta > duration else print('so fast')             return ret         return wrapper     return _logger @logger(5)  # add = logger(5)(add) def add(x,y):     time.sleep(3)     return x+y  print(add(5,6))

改进装饰器logger函数

def logger(dutation,func=lambda name,dutation:print('{} took {}s'.format(name,dutation))):     def _logger(fn):         @copy_properties(fn)         def wrapper(*args,**kwargs):             start = datetime.datetime.now()             ret = fn(*args,**kwargs)             delta = (datetime.datetime.now() - start).total_seconds()             if delta > duration:                 func(fn.__name__,duration)             return ret         return wrapper     return _logger


四、functools 模块

import datetime,time,functools  def logger(duration,func=lambda name,duration:print('{}took {}s'.format(name,duration))):           def _logger(fn):         @functools.wraps(fn)         def wrapper(*args,**kwargs):             '''I am wrapper'''             start = datetime.datetime.now()             ret = fn(*args,**kwargs)             delta = (datetime.datetime.now() - start).total_seconds()             if delta > duration:                 func(fn.__name__,duration)             return ret         return wrapper     return _logger @logger(5) def add(x,y):     '''I adm add'''     time.sleep(5)     return x+y print(add(5,6))


1、functools模块 partial方法

1、partial方法举例    :      import functools     def add(x,y) -> int:         return x + y     newadd = functools.partial(add,y=5)     print(newadd(7))     print(newadd(7,y=6))     print(newadd(y=10,x=6))      import inspect     print(inspect.signature(newadd)) 2、@functool.lru_cache(maxsize=128,type=False)装饰器     如果maxsize设置为None,则禁用LRU功能,并且缓存可以无限制增长     当maxsize是二的幂时,LRU功能执行的最好     如果typed设置为Ture,则不同类型的函数参数将单独缓存:如:f(3)和f(3.0)将被视为具有     不同结果的不同调用  3、lru_cache装饰器     通过一个字典缓存被装饰器的调用和返回值

五、参数注解

1、inspect模块

     >>> import inspect >>> def add(x:int,y:int,*args,**kwargs) -> int:         return x + y  >>> sig = inspect.signature(add) >>> print(sig) (x:int, y:int, *args, **kwargs) -> int  >>> print('params:',sig.parameters) #有序字典 params: OrderedDict([('x', <Parameter "x:int">), ('y', <Parameter "y:int">), ('args', <Parameter "*args">), ('kwargs', <Parameter "**kwargs">)])  >>> print('return:',sig.return_annotation) return: <class 'int'>  >>> print(sig.parameters['y']) y:int  >>> print(sig.parameters['args']) *args  >>> print(sig.parameters['args'].annotation) <class 'inspect._empty'> >>>       使用举例 import inspect def add(x,y:int=7,*args,z,t=10,**kwargs)-> int:     return x + y sig = inspect.signature(add) print(sig) print('params:',sig.parameters) print('return:',sig.return_annotation) print('~~~~~~~~~~') for i,iterm in enumerate(sig.parameters.items()):     name,param = iterm     print('=========',i+1,name,param.annotation,param.kind,param.default)     print(param.default is param.empty,end='\n\n')

来源: https://www.cnblogs.com/jiangzuofenghua/p/11386469.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!