brief introduction
Function is not only the basis of structured programming, but also the cornerstone of code reuse. Python uses def to customize functions. This article will explore the secrets of functions in Python.
Built in function
In addition to user-defined functions, Python has built-in some very useful functions:
Custom function
Python uses def to define functions and return to return specific values.
Take a simple function example:
def my_function(x, y, z): if z > 1: return z * (x + y) else: return z / (x + y) Copy code
The example of fiborah sequence we talked about earlier is redefined by function, which can be written as follows:
def fib(n): a, b = 0, 1 while a < n: print(a, end=' ') a, b = b, a+b print() # Call function fib(1000) Copy code
The contents of the function need to be indented with spaces or tab s.
Default values for parameters
In Python, we can set the default value for the parameter, so that if no parameter is passed during the function call, the default value will be used as the parameter.
The function my we defined earlier_ In function, we can set a default value for z:
def my_function(x, y, z=10): if z > 1: return z * (x + y) else: return z / (x + y) Copy code
So we're calling my_function can only pass two parameters, and the last z can use the default parameter value.
Note that the default value will be executed only once. If the parameters you pass in are variable objects (lists, dictionaries and class instances), we need to pay attention to this problem:
def f(a, L=[]): L.append(a) return L print(f(1)) print(f(2)) print(f(3)) # output [1] [1, 2] [1, 2, 3] Copy code
If you do not want to share the default value in subsequent calls, you can put the assignment of the default value inside the function body:
def f(a, L=None): if L is None: L = [] L.append(a) return L Copy code
Keyword parameters
We can call the function with key=value.
Or the previous function:
def my_function(x, y, z=10): if z > 1: return z * (x + y) else: return z / (x + y) Copy code
We can call:
my_function(1,y=3,z=5) my_function(1,y=3) Copy code
But it can't be used like this:
my_function(y=3,1) Copy code
Keyword parameters must be placed after non keyword parameters. You cannot assign a parameter more than once:
>>> def function(a): ... pass ... >>> function(0, a=0) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: function() got multiple values for keyword argument 'a' Copy code
From the above discussion, we can see that there are two parameters in Python functions, one with default value and the other without default value.
Note that parameters without default values must precede those with default values.
Take a wrong example:
In [69]: def fa(a=100,b,c=200): ...: pass File "<ipython-input-69-d5678b64f352>", line 1 def fa(a=100,b,c=200): ^ SyntaxError: non-default argument follows default argument Copy code
There are also two ways to pass parameters to functions, one is without keywords, and the other is with keywords.
Note that non keyword parameters must be passed before keyword parameters.
For example:
In [70]: def fa(a,b=100,c=200): ...: pass ...: In [71]: fa(a=100,30) File "<ipython-input-71-5a229b8e420e>", line 1 fa(a=100,30) ^ SyntaxError: positional argument follows keyword argument Copy code
So the question is, if there are multiple keyword parameters and multiple non keyword parameters, is there a simple way to define such a function?
Yes, they are arguments and keywords
arguments is used to receive all redundant non keyword parameters. keywords is used to receive all additional keyword parameters.
Note that * arguments must appear before * * keywords.
for instance:
def cheeseshop(kind, *arguments, **keywords): print("-- Do you have any", kind, "?") print("-- I'm sorry, we're all out of", kind) for arg in arguments: print(arg) print("-" * 40) for kw in keywords: print(kw, ":", keywords[kw]) Copy code
We can call:
cheeseshop("Limburger", "It's very runny, sir.", "It's really very, VERY runny, sir.", shopkeeper="Michael Palin", client="John Cleese", sketch="Cheese Shop Sketch") Copy code
The following results will be obtained:
-- Do you have any Limburger ? -- I'm sorry, we're all out of Limburger It's very runny, sir. It's really very, VERY runny, sir. ---------------------------------------- shopkeeper : Michael Palin client : John Cleese sketch : Cheese Shop Sketch Copy code
Special parameters
Functions can pass parameters by location, keyword, or mixed.
In some cases, we may need to limit the types of parameters passed, such as receiving only positional pass, only keyword pass, or only mixed pass.
See the definition of special parameters:
def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2): ----------- ---------- ---------- | | | | By location or keyword | | - Only passing by keyword is allowed -- Only passing by location is allowed Copy code
Note that the parameters are distinguished by / and *.
Let's take an example:
>>> def standard_arg(arg): ... print(arg) ... >>> def pos_only_arg(arg, /): ... print(arg) ... >>> def kwd_only_arg(*, arg): ... print(arg) ... >>> def combined_example(pos_only, /, standard, *, kwd_only): ... print(pos_only, standard, kwd_only) Copy code
Functions with four parameter transfer modes are defined above.
The first function is the standard form, which can be passed by location or keyword.
The second function only allows passing by location.
The third function only allows passing by keyword.
The fourth function is mixed mode.
Parameter unpacking
Sometimes we need to convert the values of a list or dictionary to the parameters of a function. Then you need to use the parameter unpacking function.
*Operators can be used to unpack lists and tuples.
>>> list(range(3, 6)) # normal call with separate arguments [3, 4, 5] >>> args = [3, 6] >>> list(range(*args)) # call with arguments unpacked from a list [3, 4, 5] Copy code
**Operators can be used to unpack dictionaries.
>>> def parrot(voltage, state='a stiff', action='voom'): ... print("-- This parrot wouldn't", action, end=' ') ... print("if you put", voltage, "volts through it.", end=' ') ... print("E's", state, "!") ... >>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"} >>> parrot(**d) Copy code
Lambda
Friends familiar with Java may know that in JDK8, Java introduces Lambda expressions. Similarly, there is Lambda in Python.
You can think of Lambda as an anonymous function. You can use Lambda expressions wherever you need functions.
Take an example of Lambda:
>>> def make_incrementor(n): ... return lambda x: x + n ... >>> f = make_incrementor(42) >>> f(0) 42 >>> f(1) 43 Copy code
You can also take the return value of lambda as a parameter:
>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')] >>> pairs.sort(key=lambda pair: pair[1]) >>> pairs [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')] Copy code
Function annotation
We discussed the simple custom function form before. We don't know the parameter type and return value type of the function. In fact, the function can be written in more detail, which requires function annotation.
The so-called function annotation is the optional metadata information of the type in the user-defined function.
Function labels are stored in the form of dictionaries__ annotations__ Property. If we add a colon to the name of the parameter followed by an expression, the expression will be evaluated as the value of the label. For the return value, the definition of the return value label is to add a combination symbol - >, followed by an expression. The label is located between the formal parameter list and the colon indicating the end of the def statement.
for instance:
>>> def f(ham: str, eggs: str = 'eggs') -> str: ... print("Annotations:", f.__annotations__) ... print("Arguments:", ham, eggs) ... return ham + ' and ' + eggs ... >>> f('spam') Annotations: {'ham': <class 'str'>, 'return': <class 'str'>, 'eggs': <class 'str'>} Arguments: spam eggs 'spam and eggs' Copy code
In fact, the program written with function annotation is clearer and more readable.