Higher order functions
Neckyan function
- Sorted (iterable[, key][, reverse])
- Filter (function, iterable)--Filter Object
- Map (func, *iterables)---Map object
Sorted (iterable[, key][, reverse]) sort
- Returns a new list of all elements of an object that can be iterated, sorted by the function defined by key, and reverse indicates whether to sort flip
Filter (function, iterable)
- Filters an element that iterates over an object, returning an iterator
- Functions a function with one parameter that returns a bool
Map (function, *iterables)---Map object
- Maps the elements of multiple, iterative objects according to the specified function, returning an iterator
Currying currying
Refers to the process of turning a function that accepts two parameters into a new function that takes a parameter. The new function returns a function with the original second argument as the argument
z = f (x, y) ==> z = f (x) (y)
- Example
Currying the addition functiondef add(x, y):return x + y
Convert as follows
def add(x):def _add(y):return x+yreturn _addadd(5)(6)
You can convert a function to a curry function by nesting functions
Decorative Device
In OOP design mode, adorners belong to a decorative mode
Decorator syntax is a syntactic sugar
def logger(func): def wrapper(*args, **kwargs): print(‘call ‘ + func.__name__) return func(*args, **kwargs) return wrapper
@logger # equivalent to add = Logger (add)
def add (x, y):
return x + y
Adorner (without reference)
- It is a function
- function as its formal parameter.
- The return value is also a function
- You can use the @functionname method to simplify calls
Adorners are higher-order functions, but adorners are decorations for functions that pass in functions (enhancements)
Document string
- In the first line of the function statement block, and is accustomed to multiple lines of text, so use three more quotes
- The formula is capitalized, the first line has an overview, an empty line, and the third line writes a detailed description
- This document can be accessed using the special properties Doc
Adorner side effects
- The properties of the original function object are replaced (the wrapper property is returned after execution), and with the adorner, our requirement is to view the properties of the encapsulated function
Workaround:
1. Provides a function, encapsulated function Property ==copy==> Wrapper function property
def copy_properties(src, dst): # 可以改造成装饰器 dst.__name__ = src.__name__ dst.__doc__ = src.__doc__
- Overriding the wrapper function's properties with the Copy_properties function
- All the functions that are decorated need to copy these properties, this function is very common
- Functions that copy properties can be constructed as adorner functions with reference adorners
2. Using Functools.update_wrapper (wrapper, wrapped)
import datetime, time, functoolsdef logger(duration, func=lambda name, duration: print(‘{} took {}s‘.format(name, duration))): def _logger(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 functools.update_wrapper(wrapper, fn) return _logger@logger(5) # add = logger(5)(add)def add(x,y): time.sleep(1) return x + yprint(add(5, 6), add.__name__, add.__wrapped__, add.__dict__, sep=‘\n‘)
3. Using @functools.wraps (wrapped)
import datetime, time, functoolsdef logger(duration, func=lambda name, duration: print(‘{} took {}s‘.format(name, duration))): def _logger(fn): @functools.wraps(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@logger(5) # add = logger(5)(add)def add(x,y): time.sleep(1) return x + yprint(add(5, 6), add.__name__, add.__wrapped__, add.__dict__, sep=‘\n‘)
With reference decorator
- It is a function function as its formal parameter.
- The return value is an adorner function with no parameters
- Called using the @functionname (parameter list) method
- can be seen as adding a layer of functions to the outer layers of the adorner.
Extract the logged functionality so that the output can be controlled flexibly through externally provided functions
Parameter annotations
Shaped like:
def add(x:int , y:int) -> int :‘‘‘:param x: int:param y: int:return: int‘‘‘return x + y
- Python 3.5 Introduction
- Type annotations on the parameters of a function
- Type annotation of the return value of a function
- Only an auxiliary description of the function parameters is done, and the function arguments are not type checked
- Provide to third-party tools, do code analysis, find hidden bugs
- Information for function annotations, stored in the annotations property
- The key is the parameter name and the value is class type
Variable annotations use less
Inspect module
Signature (callable), returns a Signature class object. Get a signature (the function signature contains information about a function, including the function name, its parameter type, the class and namespace it resides in, and other information)
sig = signature(fn)params = sig.parameters
The parameters method of the Signature class object returns a ordereddict whose key value is the parameter name of the FN, and the value is the parameter class object
Parameter Object
Saved in a tuple, is read-only
- Name, names of parameters
- annotation, parameter annotations, may not be defined
- Default, parameter defaults, may not be defined
- Empty, special class for marking the default property or the null value of the comment annotation property
- Kind, how the argument is bound to the formal parameter, which is the type of the formal parameter
- Positional_only, the value must be a positional parameter provided #Python没有实现次形参类型
- Positional_or_keyword, values can be provided as keywords or positional parameters
- var_positional, variable position parameter, corresponding *args
- Keyword_only,keyword-only parameter, corresponding to the non-mutable keyword parameter after the args
- Var_keyword, variable keyword parameter, corresponding to **kwargs
Business Applications
import inspectdef check(fn): def wrapper(*args,**kwargs): sig = inspect.signature(fn) params = sig.parameters #是orderedDict values = list(params.values()) #可迭代对象转化成列表,处理后也是有序的 for k,v in enumerate(args): #因为values、args都有序 if values[k].annotation is not inspect._empty and not isinstance(v,values[k].annotation): return ‘{}`s input is {} type , expected {}‘.format(v,type(v),values[k].annotation) for k,v in kwargs.items(): #kwargs与params都为字典形式,键值相同 if params[k].annotation is not inspect._empty and not isinstance(v, params[k].annotation): return ‘{}`s input is {} type , expected {}‘.format(k,type(v),params[k].annotation) return fn(*args,**kwargs) return wrapper@checkdef add(x:int,y:int): return x + y
Functools Module Partial function partial
- The parameter of the function part is fixed, which is equivalent to adding a fixed default value for some parameters, forming a new function and returning
- The new function generated from partial is the encapsulation of the original function.
Partial Source code Logic
def partial(func, *args, **keywords):def newfunc(*fargs, **fkeywords): # 包装函数newkeywords = keywords.copy() #将原函数关键字参数拷贝后,newkeywords.update(fkeywords) #将调用新函数时的关键字参数更新return func(*(args + fargs), **newkeywords) #调用新函数时的参数是建立偏函数时给的参 #数,再各加上调用新函数时的参newfunc.func = func # 保留原函数,注意:如果原函数已有装饰器,func属性内容有可能不是原函数名,而是装饰器函数名newfunc.args = args # 保留原函数的位置参数newfunc.keywords = keywords # 保留原函数的关键字参数参数return newfunc
- Partial () returns a new function Newfunc, and Newfunc returns the original function, whose arguments are the arguments given when the partial function is created, plus the arguments when the new function is called
LRU Cache Adorner
- @functools. Lru_cache (maxsize=128, Typed=false)
- least-recently-used decorator. LRU, least recently used. Cache caching
- If MaxSize is set to None, the LRU feature is disabled and the cache can grow indefinitely. The LRU function performs best when the maxsize is a power of two
If typed is set to True, the different types of function parameters are cached separately. For example, F (3) and F (3.0) will be treated as different calls with different results
- The call and return value of the decorated function is cached through a dictionary
If all positional arguments are the same as the values, the same argument is considered, or the Quan zhuan keyword parameter is considered the same argument even if the order is different, that is, the cache can be used, and other cases are considered different arguments
- Lru_cache using _make_key to generate the parameter cache
Source:
def _make_key(args, kwds, typed, kwd_mark = (object(),), fasttypes = {int, str, frozenset, type(None)}, tuple=tuple, type=type, len=len):"""Make a cache key from optionally typed positional and keyword argumentsThe key is constructed in a way that is flat as possible rather thanas a nested structure that would take more memory.If there is only a single argument and its data type is known to cacheits hash value, then that argument is returned without a wrapper. Thissaves space and improves lookup speed."""key = argsif kwds: key += kwd_mark for item in kwds.items(): key += itemif typed: key += tuple(type(v) for v in args) if kwds: key += tuple(type(v) for v in kwds.values())elif len(key) == 1 and type(key[0]) in fasttypes: return key[0]return _HashedSeq(key)
Lru_cache Decorator Application
- Usage Prerequisites
- The same function parameter must have the same result.
- function execution takes a long time and executes multiple times
- The essence is the parameter of the function call = = return value
- Disadvantages
- Cache expiration not supported, key cannot expire, fail
- Clear Operation not supported
- Does not support distributed, is a single-machine cache
- Application scenarios, where space is required on a single machine to change the time, you can use the cache to turn the calculation into a fast query
Python Fifth Week study notes (1)