Functions of Python Basics - Part 2

The previous two articles recorded the basic definition of the function and the use of parameters ( click here to view the previous article ). This article focuses on describing the variable scope of the function and the use of iterators and decorators. Without further ado, let’s start!

1. Variable scope

Python variables roughly include built-in variables, global variables, closure variables, local variables, etc., and the order of access is local variables-closure variables-global variables-built-in variables.

1.1 Built-in variables

There are some constants and functions built into the python interpreter, called built-in variables or built-in constants, such as list, int, etc. You can enter in python IDLE: dir(__builtins__)view, as shown below:

insert image description here

1.2 Global variables

Global variables, as the name suggests, are variables that can be used globally, such as in the entire file, the entire code block, or a function. like:

num = 20
def func():
    print(num)
func()

At this time, num is a global variable and can be used in the function func().
Note : If you try to modify a global variable within a function, python will automatically create a new local variable instead with the same name as the global variable. But the two variables are actually two independent variables with different storage spaces. Python will automatically shield newly created local variables and protect global variables. So don't easily modify global variables in functions, they can be accessed. Use global variables with caution. like:

name = "jsonwong"
def func():
    new_name = name[:5]
    return new_name
print(func())
print(name)

The output is:

jsonw
jsonwong

1.3 Closure variables

Before explaining closure variables, it is necessary to explain what closures are. Baidu Encyclopedia's explanation of closures is: "
Closure: From the definition of expression, if in an internal function, a variable in the external scope (but not in the global scope) is referenced, then the internal function will be considered as a closure."

Definition of closure :
1. A closure is a function nested within a function.
2. The closure must be a reference to a variable (non-global variable) of the inner function to the outer function.
The function of the closure:
to save the local information from being destroyed, and to ensure the security of the data.
Application of closures:
1. Ensure data security.
2. The nature of the decorator.
like:

def make_average():
    l1 = [1000, 1000, 1000, 2000]
    def average(price):
        l1.append(price)
        total = sum(l1)
        return total/len(l1)
    return average
avg = make_average()
print(type(avg))
print(avg(1000))

The output is:

<class 'function'>
1200.0

At this time, l1 in the function make_average is the closure variable.

1.4 Local variables

Local variables: The parameters and variables defined in the function are all local variables and cannot be used outside the function. For example, in 1.3, total is a local variable. Note that local variables can only be used inside the function, and cannot be used outside the function! like:

def func(num):
    s = 0
    print(s*num)
func(5)

The variable s at this time is a local variable. But if you use local variables outside the function, an error will be reported, such as:

def func(num):
    s = 0
    print(s*num)
func(5)
print(s)

Prompt error:

NameError: name 's' is not defined

globleThe correct way is to make local variables into global variables, and add keywords before the variables , such as:

def func(num):
    global s
    s = 0
    print(s*num)
func(5)
print(s)

output:

0
0

Local variables can access closure variables, but cannot modify them!

Two, iterator

2.1 Iterators

There are some Python objects from which we can extract elements in a certain order. These objects are called iterable objects. For example, strings, lists, tuples, sets, and dictionaries are all iterable objects. In fact, the essence of for loop is iterator loop.
Advantages of the iterator:
    1. Provides a general iterative method that does not depend on the index
    2. There is only one value in the memory at the same time, which saves memory.     Disadvantages of the iterator: 1. The value is not as flexible as the index method. You cannot take a specified value, you can only take it backwards, not forwards     2. The length of the iterator cannot be
predicted

2.2 Generator

Generators are a convenient way to create iterators. A generator is a special kind of function. As long as the function contains the yield keyword, the calling function will not execute the code of the function body, and will get a return value, which is the generator object. like:

def func():
    print(1)
    yield 1
    print(2)
    yield 2
g = func()
print(g)

At this time, calling the function func() will not execute the code of the function body, but will get a return value, which is the generator object. The result is as follows:

<generator object func at 0x000001BFF82E64F8>

If you use next, it will trigger the execution of the function until it encounters a yield and stop, and return the value after yield as the result of next, such as:

def func():
    print(1)
    yield 1
    print(2)
    yield 2
g = func()
result_1 = next(g)
print(result_1)
result_2 = next(g)
print(result_2)

output:

1
1
2
2

Note : 1. The generator saves the algorithm, while the list saves the content in memory. The list is not dominant and consumes memory, and the generator saves memory overhead.
2. Yield vs. return: the same point, both can return a value, and there is no limit to the type and number of values.
The difference: yield can return a value multiple times, and return can only return a value once and the function will end.

2.3 Judging iterators and generators

from collections.abc import Iterable
from inspect import isgeneratorfunction

def func():
    print(1)
    yield 1
    print(2)
    yield 2
gs = (x for x in range(1, 10))

print(isinstance(gs, Iterable))
print(isgeneratorfunction(func))

output:

True
True

3. Decorator

3.1 Common decorators

As the name suggests, the decorator is to add new functions without changing the original functions of some functions
: when the program code is running, the functions are dynamically added.
Essence: It is a closure that returns the higher-order function of the function.
The benefits follow the principle of sequential opening and closing, which is closed for modification and open for extension.
Suppose now there are two functions demo() and func(), and I need to use the same function of demo in func, so this is the only way:

def demo():
    print("demo func")
def func():
    print("demo func")
    print("func")

Now to reduce the code, we can do this:

def demo(func):
    print("demo func")
    func()

def y():
    print("func")

demo(y)

But the original func () changed to demo (y) to destroy the original code logic, but the decorator can solve this problem. The decorator uses @+ decoration function to decorate the function to be decorated.

def demo(y):
    print("demo func")
    y()
@demo
def func():
    print("func")

Now it's just a matter of calling func().

3.2 Decorators with parameters

Decorators with parameters provide more flexibility in writing and using decorators.
Note:
The decorator function is executed immediately after the decorated function is defined.

def demo(func):
    print("我是装饰器")
    def inner(age):
        if age <= 10:
            mystr = "children"
        elif age <= 20:
            mystr = "midman"
        else:
            mystr = "oldman"
        return func(mystr)
    return inner

@demo
def y(p):
    print("你是一个这样的", p)
y(14)

4. Reference articles:

https://blog.csdn.net/love_Aym/article/details/76470475
https://www.cnblogs.com/changyifei-8/p/11064445.html
https://www.cnblogs.com/louyefeng/p/9430415.html
https://www.cnblogs.com/guodengjian/articles/9134944.html

Guess you like

Origin blog.csdn.net/JaysonWong/article/details/105269965