Python Functional programming
Functions are reusable pieces of program code , stay Python The built-in functions are commonly used , for example len()、sum() etc. . stay Pyhon You can also customize functions in modules and programs , Using functions can improve programming efficiency
1. Overview of functional programming
1.1 What is functional programming ?
Functional programming uses a series of functions to solve problems . Function only takes input and produces output , Does not contain any internal state that can affect the output . In any case , Calling a function with the same parameters always produces the same result .
In a functional program , Input data “ Flow through ” A series of functions , Each function produces an output based on its input . Functional style avoids writing with “ Boundary effect ”(side effects) Function of : Modify internal status , Or other changes that cannot be reflected in the output . A function that has no boundary effect at all is called “ Purely functional ”(purely functional). Avoiding boundary effects means not using data structures that can be changed while the program is running , The output depends only on the input .
Functional programming is the opposite of object-oriented programming . Objects usually contain internal states ( Field ), And many functions that can modify these States , Programs consist of constantly changing states ; Functional programming tries to avoid state changes , And work by passing data flow between functions . But that's not to say that you can't use functional programming and object-oriented programming at the same time , in fact , Complex systems are usually modeled using object-oriented technology , But mixing functional styles also gives you the added benefit of functional styles .
1.2 Why functional programming ?
The functional style is generally considered to have the following advantages :
- Logic can prove
This is an academic advantage : No boundary effect makes it easier to logically prove that the program is correct ( Instead of passing the test ).
- modularization
Functional programming advocates simplicity , A function does only one thing , Break down big functions into as small modules as possible . Small functions are easier to read and check for errors .
- Componentization
Small functions are easier to combine to form new functions .
- Easy to debug
Detailed 、 Well defined functions make debugging easier . When the program doesn't work properly , Each function is the interface to check whether the data is correct , It's faster to get rid of code that doesn't have problems , Locate the problem .
- Easy to test
Functions that do not depend on the state of the system do not need to construct test posts before testing , Make it easier to write unit tests .
- Higher productivity
Functional programming produces less code than other technologies ( It's often about half of the other technologies ), And it's easier to read and maintain .
2. Functional style
2.1 iterator (Iterator)
An iterator is an object that remembers the traversal location .
The iterator object is accessed from the first element of the collection , Until all elements are accessed . Iterators can only move forward and not backward .
There are two basic ways to iterator :iter() and next().
Create an iterator :
Using a class as an iterator requires implementing two methods in the class __iter__() And __next__() .
__iter__() Method returns a special iterator object , This iterator object implements __next__() Method and pass StopIteration The exception marks the completion of the iteration .
__next__() Method (Python 2 Is in the next()) The next iterator object is returned .
Example :
Create an iterator that returns a number , The initial value is 1, Gradually increasing 1:
2.2 generator (generator)
stay Python in , Used yield The function of the is called the generator (generator).
Different from ordinary functions , A generator is a function that returns an iterator , Can only be used for iterative operations , It's easier to understand that a generator is an iterator .
During the call generator run , Every encounter yield Function will pause and save all current running information , return yield Value , And next time next() Method to continue from the current location .
Call a generator function , Returns an iterator object .
Example :
Use yield Realization of Fibonacci series :
Add :yield sketch
yield It's a similar return Key words of , Iterate and meet yield When it returns yield Back ( On the right ) Value , And remember this return location , The next iteration is from this position ( The next line ) Start . with yield The function of is no longer a normal function , It's a generator generator, Can be used to iterate .
yield benefits :
1. It doesn't take all the data out and store it in memory , Instead, it returns an object , Data can be obtained through objects , Take as many as you like , Can save content space .
2. In addition to being able to return a value , It doesn't stop the cycle ;
adopt next() Can recover Generator perform , Until the next yield.send() It can deliver yield Value ,send() In a certain sense, with next() Having similar effects ,next() and send(None) It's the same thing . Be careful : When the generator starts ( First call ), Please use next() Statement or send(None), Can't send a non directly None Value , Otherwise it will be reported TypeError, Because no yield Statement to receive the value .
Example :
2.3 List derivation ( List of analytical ) And generator expressions
List of analytical (List comprehensions)
List parsing is an iterative object ( As listing ) Tool to convert to another list . In the process of transformation , You can specify that an element must meet certain conditions , And convert according to the specified expression , To add to a new list .
grammar : [expression for iter_var in iterable1] [expression for iter_var2 in iterable2 ... for iter_varN in iterableN] [expression for iter_var in iterable1 if condition] perform : iteration iterable All the elements in , Every iteration puts iterable Put the content in iter_var In the object , Then apply this object to the expression expression in , Generate a list .
Example :
Generator Expressions (Generator expressions)
Don't create lists , It just returns a generator . This generator calculates one entry at a time , To generate this entry . So when it comes to dealing with large amounts of data .
grammar : (expression for iter_var in iterable1) (expression for iter_var2 in iterable2 ... for iter_varN in iterableN) (expression for iter_var in iterable1 if condition) perform : iteration iterable All the elements in , Every iteration puts iterable Put the content in iter_var In the object , Then apply this object to the expression expression in , Generate a generator .
2.4 Decorator
2.4.1 Closure
Definition of closure :
An inner function is defined in an outer function , The temporary variable of the outer function is used in the inner function , And the return value of the outer function is the reference of the inner function . This constitutes a closure .
Free variable :
The external scope variables referenced by closures are called free variables . The reference free variable in the closure is only related to the specific closure , Each instance of the closure refers to free variables that do not interfere with each other . Changes to its free variables by a closure instance are passed on to the next call to the closure instance .
What you need to pay attention to when closing a free variable :
1. If a free variable is a mutable object (list,map... It's not listed here tuple Because tuple It's an unchangeable object ), So closures can update free variables .
2. If a free variable is an immutable object ( The number , Character channeling ,tuple...), Then closures can't update free variables .
Example :
2.4.2 Decorator
The decorator is essentially a Python A function or class , It allows other functions or classes to add extra functionality without any code changes , The return value of the decorator is also a function / Class object . It is often used in scenarios with faceted requirements , such as : Inserting log 、 Performance testing 、 Transaction processing 、 cache 、 Permission check and other scenarios , Decorators are an excellent design for this type of problem . We have decorators , We can extract a lot of the same code that has nothing to do with the function itself and reuse it again . General speaking , The purpose of a decorator is to add extra functionality to existing objects .
Examples of simple decorators :
Defines a decorator that prints out the method name and its parameters
import functools def log(func): @functools.wraps(func) def wrapper(*args, **kwargs): print('call %s():' % func.__name__) print('args = {}'.format(*args)) return func(*args, **kwargs) return wrapper
Use grammar sugar @ Call the decorator
@log def test(p): print(test.__name__ + " param: " + p) test("I'm a param")
Output :
call test(): args = I'm a param test param: I'm a param
Parameter decorator
Decorators with parameters will have three levels of functions , Examples are as follows
import functools def log_with_param(text): def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): print('call %s():' % func.__name__) print('args = {}'.format(*args)) print('log_param = {}'.format(text)) return func(*args, **kwargs) return wrapper return decorator @log_with_param("param") def test_with_param(p): print(test_with_param.__name__)
Output :
call test_with_param(): args = I'm a param log_param = param test_with_param
notes :@wraps Accept a function to decorate , And added the copy function name 、 Annotation document 、 Parameter list and so on . This allows us to access the properties of the function before the decoration in the decorator .
2.5 Partial function
3. Higher order function
3.1 Definition of higher order function
python If you pass a function name to another function as a formal parameter , So this function is a higher order function .
Example :
3.2 Commonly used built-in high-order functions
3.2.1 Anonymous functions
python Use lambda To create anonymous functions .
• lambda It's just an expression , Function volume ratio def Simple a lot .
• lambda The subject of is an expression , Not a block of code . Only in lambda Expressions encapsulate limited logic .
• lambda Function has its own namespace , And can't access parameters outside of its own parameter list or in the global namespace .
• although lambda The function looks like it can only write one line , But it's not the same as C or C++ Inline function , The purpose of the latter is not to occupy stack memory when calling small functions so as to increase the running efficiency .
grammar
lambda The syntax of a function contains only one statement , as follows :
lambda [arg1 [,arg2,.....argn]]:expression
Example :
3.2.2 map
map() The specified sequence will be mapped according to the function provided .
The first parameter function Call... With each element in the parameter sequence function function , Return contain every time function Function returns the value of Iterator.
grammar map() Function syntax : map(function, iterable, ...) Parameters function -- function iterable -- One or more sequences Return value The iterator that holds the result
Example :
3.2.3 reduce
reduce() The function accumulates elements in a sequence of parameters .
Function to set a data set ( Linked list , Tuples etc. ) Do the following for all data in : Pass it on to reduce The function in function( There are two parameters ) Let's start with the... In the set 1、2 Elements to operate , The results are then used with the third data function Function operation , Finally, we get a result .
grammar reduce() Function syntax : reduce(function, iterable[, initializer]) Parameters • function -- function , There are two parameters • iterable -- Iteratable object • initializer -- Optional , Initial parameter Return value Return the result of function calculation
Example :
3.2.4 filter
filter() Function to filter the sequence , Filter out the elements that do not meet the conditions , Returns a new list of eligible elements .
This accepts two parameters , The first one is a function , The second is the sequence , Each element of the sequence is passed to the function as a parameter to be judged , Then return True or False, And then it will return True Is placed in the new list .
grammar filter() The grammar of the method : filter(function, iterable) Parameters • function -- Judgment function . • iterable -- Iteratable object . Return value The iterator after filtering
Example :
Filter out all containing strings “str” 's words
3.2.5 sorted
sorted() Function to sort all objects that can be iterated .
sort And sorted difference :
sort Is used in the list The method on the ,sorted You can sort all iterable objects .
list Of sort Method returns an operation on an existing list , No return value , And built-in functions sorted Method returns a new one list, Instead of operating on the basis of the original .
grammar sorted grammar : sorted(iterable, cmp=None, key=None, reverse=False) Parameter description : iterable -- Iteratable object . cmp -- The function of comparison , This has two parameters , The values of the parameters are taken from the iteratable objects , The rule that this function must follow is , Greater than returns 1, Less than returns -1, Is equal to returns 0. key -- It's basically a comparison element , There is only one parameter , The parameters of the specific function are taken from the iterable object , Specifies an element in an iterable object to sort . reverse -- Sort rule ,reverse = True Descending , reverse = False Ascending ( Default ). Return value Return to the reordered list
Example :
3.2.6 zip
zip() Function to take iteratable objects as parameters , Package the corresponding elements in the object into tuples , And then it returns the tuple of zip Type object .
If the number of elements in each iterator is inconsistent , Returns a list of the same length as the shortest object , utilize * The operator , Tuples can be unzipped into lists .
grammar zip grammar : zip([iterable, ...]) Parameter description : iterabl -- One or more iterators ; Return value Return to one zip Type object
Example :
3.3 The combination of higher order functions
notes : Part of the content of the blog is reproduced in Python Functional programming guide ( One ): summary