Introduction to the

Functions are the foundation of structured programming and the cornerstone of code reuse. Python uses def to customize functions. This article delves into the secrets of functions in Python.

Built-in function

In addition to the user’s custom functions, Python has some very useful built-in functions:

Built-in function
abs() delattr() hash() memoryview() set()
all() dict() help() min() setattr()
any() dir() hex() next() slice()
ascii() divmod() id() object() sorted()
bin() enumerate() input() oct() staticmethod()
bool() eval() int() open() str()
breakpoint() exec() isinstance() ord() sum()
bytearray() filter() issubclass() pow() super()
bytes() float() iter() print() tuple()
callable() format() len() property() type()
chr() frozenset() list() range() vars()
classmethod() getattr() locals() repr() zip()
compile() globals() map() reversed() __import__()
complex() hasattr() max() round()

Custom function

Python uses def to define functions and return to return specific values.

Look at an example of a simple function:

def my_function(x, y, z):
      if z > 1:
         return z * (x + y)
     else:
         return z / (x + y)
Copy the code

To redefine the Fibolach sequence as a function, we could write it like this:

def fib(n):   
     a, b = 0, 1
     while a < n:
         print(a, end=' ')
         a, b = b, a+b
     print()
     
#Call a function
fib(1000)
Copy the code

The contents of a function need to be indented with Spaces or tabs.

The default value of the parameter

In Python, we can set default values for arguments so that if no arguments are passed during a function call, the default values will be used as arguments.

In the function my_function we defined earlier, 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 the code

This way we can call my_function with only two arguments and use the default values for the final z.

Note that the default value is executed only once, if you pass in mutable objects (lists, dictionaries, and class instances), we need to pay attention to this:

def f(a, L=[]):
    L.append(a)
    return L

print(f(1))
print(f(2))
print(f(3))

#The output
[1]
[1, 2]
[1, 2, 3]
Copy the code

If you do not want to share the default values in subsequent calls, you can place the assignment of the default values inside the function body:

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L
Copy the code

Keyword parameter

We can call the function with key=value.

Again, the previous function:

def my_function(x, y, z=10):
      if z > 1:
         return z * (x + y)
     else:
         return z / (x + y)
Copy the code

We can call it like this:

my_function(1,y=3,z=5)
my_function(1,y=3)
Copy the code

But don’t use it like this:

My_function (y = 3, 1)Copy the code

Keyword arguments must be placed after non-keyword arguments. Nor can arguments be assigned 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 the code

As you can see from the above discussion, there are two kinds of arguments in Python functions: arguments with default values and arguments without default values.

Note that arguments without default values must precede arguments with default values.

Here’s an example of a mistake:

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 argumentCopy the code

There are also two ways to pass parameters to a function, one is pass without keyword, the other is pass with keyword.

Note that non-keyword arguments must be passed before keyword arguments are passed.

Here’s a wrong 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 argumentCopy the code

So, if you have multiple keyword arguments and multiple non-keyword arguments, is there an easy way to define such a function?

Arguments and **keywords

*arguments is used to accept all redundant non-keyword arguments. The **keywords are used to receive all the additional keyword parameters.

Note that *arguments must appear before **keywords.

Here’s an example:

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 the code

We can call it like this:

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 the code

You get the following result:

-- 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 the code

Special parameters

Functions can be passed by position, by keyword, or by a mixture of parameters.

In some cases, we may need to limit the type of passing parameters, such as only accepting passing by location, only accepting passing by keyword, or only accepting mixed passing.

Take a look at the definition of a special parameter:

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2) :-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - | | | | according to location or keyword | | - allows only according to the keywords to pass - only allowed according to the positionCopy the code

Note that 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 the code

The above defines functions that pass parameters in four ways.

The first function is in standard form and can be passed by position or keyword.

The second function only allows passing by position.

The third function is only allowed to be passed by keyword.

The fourth function is mixed mode.

Parameters to unpack

Sometimes we need to convert a list or dictionary value to a function parameter. Then you need to use the parameter unpacking function.

The * operator 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 the code

The ** operator 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 the code

Lambda

Those familiar with Java may know that in JDK8, Java introduced Lambda expressions. Similarly, Python has Lambda.

You can think of Lambda as an anonymous function. Lambda expressions can be used wherever functions are needed.

Look at an example of Lambda:

>>> def make_incrementor(n) :
.    return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43
Copy the code

You can also take the return value of lambda as an argument:

>>> 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 the code

Function annotation

Before, we discussed the simple custom function form. We did not know the parameter type and return value type of the function. In fact, the function can be written in more detail, which uses the function annotation.

Function annotations are optional metadata information about types in user-defined functions.

Function annotations are stored as dictionaries in the __annotations__ attribute. We append the parameter name with a colon followed by an expression that will be evaluated to the value of the annotation. For a return value, the return value annotation is defined by a composite symbol -> followed by an expression between the parameter list and the colon indicating the end of the DEF statement.

Here’s an example:

>>> 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 the code

In fact, using function annotation to write the program is clearer, more readable.

This article is available at www.flydean.com/05-python-f…

The most popular interpretation, the most profound dry goods, the most concise tutorial, many tips you didn’t know waiting for you to discover!

Welcome to pay attention to my public number: “procedures those things”, understand technology, more understand you!