Python learning notes: functions! OVER!

introduction

When Python code is running, what functions do? After the Python interpreter starts to execute, it opens up a space in memory. Whenever it encounters a variable, it records the corresponding relationship between the variable name and value. However, when it encounters the function definition, the interpreter only reads the function name symbolically, such as memory, The interpreter doesn't care about the variables and logic inside the function.

When the function is called, the Python interpreter will open up another memory to store the contents of the function. At this time, it will pay attention to the variables in the function, and the variables in the function will be stored in the newly opened memory. The variables in the function can only be used inside the function and will be used as the function is executed, All the contents of this memory will also be emptied.

We give a name to the space for storing the relationship between name and value ---- namespace.
At the beginning of the code, the space created to store the "relationship between variable name and value" is called the global namespace;
The temporary space opened up during the operation of a function is called a local namespace.

Namespace and scope

As mentioned in the python Zen: namespace is a wonderful idea. Let's use it as much as we can!

There are three types of namespaces:

Global Namespace
Local namespace
Built in namespace

The built-in namespace stores the names provided by the python interpreter for us: input,print,str,list,tuple... They are all familiar methods that we can use when we take them.
Loading and value sequence among the three namespaces:
Loading order: built in namespace (loaded before program running) - > global namespace (loaded from top to bottom during program running) - > local namespace (loaded only when calling during program running)
Value sequence:
Call locally: local namespace - > global namespace - > built-in namespace
Call globally: global namespace - > built-in namespace
To sum up, when looking for variables, look from small range, layer by layer to large range.

Scope

Scope is the scope. According to the effective scope, it can be divided into global scope and local scope.
Global scope: contains built-in namespace and global namespace, which can be referenced anywhere in the whole file and is globally valid
Local scope: local namespace. It can only take effect in a local scope

globals and locals methods

def func():
    a = 12
    b = 20
    print(locals())
    print(globals())
func()
output
{'a': 12, 'b': 20}
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000023590866400>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/pythonProject1/main.py', '__cached__': None, 'func': <function func at 0x000002359081C268>}

global keyword, nonlocal keyword

global
1. Declare a global variable.
2. When the local scope wants to modify the global variables of the global scope, it needs to use global (limited to strings and numbers).

def func():
    global a
    a = 3
func()
print(a)

count = 1
def search():
    global count
    count = 2
search()
print(count)
output
3
2

Note: variable data types (list, dict, set) can be directly referenced without global.

li = [1,2,3]
dic = {'a':'b'}
 
def change():
    li.append('a')
    dic['q'] = 'g'
    print(dic)
    print(li)
change()
print(li)
print(dic)

nonlocal:

1. Global variables cannot be modified.
2. In the local scope, the variables of the parent scope (or the outer scope is not the global scope) are referenced and modified, and the referenced layer is changed from that layer and below.

def add_b():
    b = 42
    def do_global():
        b = 10
        print(b)
        def dd_nonlocal():
            nonlocal b
            b = b + 20
            print(b)
        dd_nonlocal()
        print(b)
    do_global()
    print(b)
add_b()
Output:
10
30
30
42

Nesting and scope chain of functions

Function name essence

The function name is essentially the memory address of the function.

1. Can be referenced

def func():
    print('in func')
f = func
print(f)
<function func at 0x000001E889788D08>

2. Elements that can be treated as container types

def f1():
    print('f1')
def f2():
    print('f2')
def f3():
    print('f3')
l = [f1,f2,f3]
d = {'f1':f1,'f2':f2,'f3':f3}
#call
l[0]()
d['f2']()
Output:
f1
f2

3. It can be used as the parameter and return value of the function

def f1():
    print('f1')
def func1(argv):
    argv()
    return argv
f = func1(f1)
f()
Output:
f1
f1

The first class object refers to
1. It can be created during operation
2. It can be used as a function parameter or return value
3. Entities that can be stored in variables.
don't get it? Then remember a sentence, just use it as an ordinary variable

Closure function

An internal function contains a reference to an external scope rather than a global scope variable. The internal function is called a closure function
Functions defined internally are called internal functions
Because of the scope, we can't get the variables and functions inside the function. What if we just want to take it? Go back!
We all know that if we want to use the variable inside the function outside the function, we can directly return this variable. What if we want to call the function inside the function outside the function?
Just return the name of this function directly?
This is the most common use of closure functions

example

def func():
    name = 'eva'
    def inner():
        print(name)
    return inner
f = func()
f()
output
eva

Method of judging closure function__ closure__

#Output__ closure__ There is a cell element: it is a closure function

def func():
    name = 'eva'
    def inner():
        print(name)
    print(inner.__closure__)
    return inner
 
f = func()
f()
#Output__ closure__ Is None: not a closure function
name = 'egon'
def func2():
    def inner():
        print(name)
    print(inner.__closure__)
    return inner
f2 = func2()
f2()
Output:
(<cell at 0x00000288A894CA38: str object at 0x00000288A8922378>,)
eva
None
egon
def wrapper():
    money = 1000
    def func():
        name = 'eva'
        def inner():
            print(name, money)
        return inner
    return func
f = wrapper()
i = f()
i()
Output:
eva 1000

Tags: Python Pycharm

Posted on Sat, 18 Sep 2021 12:44:19 -0400 by dukeu03