Function object, scope and name space

Function object

Functions are first-class objects, i.e. function as data that can be processed.

def func():
    print('from func')


print(func())
from func
None

Four functions function object

1. references

x = 'hello william'
y = x

f = func()
print(f)
from func
None

2. as a parameter passed to a function

z = len(x)


def foo(m):
    m()


foo(func)

3. The return value can be used as a function of

def foo(x):
    return x


res = foo(func)
print(res)
res()

4. The types of elements can be used as a container

l = [x]

function_list = [func]
print(function_list[0]())
from func

Exercise

def pay():
    print('支付1e成功')


def withdraw():
    print('提现2e成功')


dic = {
    '1': pay,
    '2': withdraw
}

while True:
    msg = """
    '1':支付,
    '2':提现,
    '3':退出,
    """

    print(msg)
    choice = input('>>:').strip()
    if choice == '3':
        break
    elif choice in dic:
        dic[choice]()
    '1':支付,
    '2':提现,
    '3':退出,
    
>>:1
支付1e成功

    '1':支付,
    '2':提现,
    '3':退出,
    
>>:2
提现2e成功

    '1':支付,
    '2':提现,
    '3':退出,
    
>>:3

Nested functions

Nested function definition

Internal function defined functions can not be used inside a function defined in an external function.

def f1():
    def f2():
        print('from f2')
    f2()


f1()
# f2()   # name 'f2' is not defined
from f2

Now, with a demand by a function to pass parameters to obtain the area or perimeter of a circle. That is thrown into the pile of tools within the toolbox, and then want to get a tool, available directly from the toolbox on the line.

from math import pi


def circle(radius, action='area'):
    def area():
        return pi*(radius**2)

    def perimeter():
        return 2*pi*radius

    if action == 'area':
        return area()
    else:
        return perimeter()


print(f'circle(10):{circle(10)}')
print(f"circle(10,action='perimeter'):{circle(10,action='perimeter')}")
circle(10):314.1592653589793
circle(10,action='perimeter'):62.83185307179586

Nested function calls

def max2(x, y):
    if x > y:
        return x
    else:
        return y


def max4(a, b, c, d):
    res1 = max2(a, b)
    res2 = max2(res1, c)
    res3 = max2(res2, d)
    return res3


print(max4(2, 3, 4, 1))
4

Namespace and scope

Function inside the function only inside the function call, you can not call outside the function, then we know why this situation.

Namespaces

Namespace (name spaces): Before we learned to create variable is actually opened up a new space in memory. But we avoided the storage variable name, in fact, there is room for a binding relationship between a variable name and variable memory storage in memory, and this space is called a namespace.

Built-in namespace

Built-in namespace: Store python interpreter that comes with the name, such asint、float、len

Life cycle: when the interpreter started to take effect, expire at the close interpreter.

Global name space

Global namespace: In addition to the built-in and a local name, the rest are stored in the global namespace, such as the following codex、func、1、z

Life cycle: when the file is executed into effect, expire after file execution.

x = 1


def func():
    pass


l = [1, 2]

if 3 > 2:
    if 4 > 3:
        z = 3

The local name space

The local name space: the name of the function body for storing generated during a function call, such as the following codef2

Life Cycle: take effect during the function call when the file is executed, expire after the function execution.

def f1():
    def f2():
        print('from f2')
    f2()


f1()

Loading order

Because .py file is opened by the Python interpreter, so it must be built after the name space in Python interpreter has finished loading, began to open the file, this time will produce a global name space, but there is a certain function in the file when called, it will begin to produce local name space, the name space for the loading order: built -> global -> local.

Find the order

As the name space is used to store a binding relationship between the variable name and value, so whenever you want to find the name, it must be found in one of the three, look for the following order:

Find the current location, location if the current location is the local name space, the search order to: Local ---> Global ---> built.

x = 1
y = 2
len = 100


def func():
    y = 3
    len = 1000
    print(f'y:{y}')
    print(f'len:{len}')
    # print(a)  # NameError: name 'a' is not defined


func()
y:3
len:1000
x = 1


def func():
    print(x)


x = 10
func()
10

Scope

Domain refers to a region, i.e. the region scope of action.

Global scope

Global Scope: Global effective, global survival, including built-in namespace and global name space.

# 全局作用域
x = 1


def bar():
    print(x)


bar()
1

Local scope

The local scope: partially valid, temporary storage, containing only the local name space.

# 局部作用域
def f1():
    def f2():
        def f3():
            print(x)
        x = 2
        f3()
    x = 3
    f2()


f1()
2

important point

Note that: the scope of the relationship between the function definition stage fixed die, regardless of the function was called.

# 作用域注意点
x = 1


def f1():  # 定义阶段 x = 1
    print(x)


def f2():
    x = 2
    f1()


f2()
1

The scope of application function object +

# 作用域应用
def f1():
    def inner():
        print('from inner')
    return inner


f = f1()  # 把局部定义的函数放在全局之中


def bar():
    f()


bar()
from inner

Supplementary knowledge

global keyword

Modify variables in global scope.

x = 1


def f1():
    x = 2

    def f2():
        global x  # 修改全局变量
        x = 3
    f2()


f1()
print(x)
3

nonlocal keyword

Modify variables local scope.

x = 1


def f1():
    x = 2

    def f2():
        nonlocal x
        x = 3

    f2()
    print(x)


f1()
3

important point

  1. In the local want to modify the global variable type, it does not require any statement can be modified directly.
  2. In the local immutable type if you want to modify global, the need to use global statement, declared as global variables can be modified directly.
lis = []


def f1():
    lis.append(1)


print(f"调用函数前:{lis}")
f1()
print(f'调动函数后:{lis}')
调用函数前:[]
调动函数后:[1]

Guess you like

Origin www.cnblogs.com/WilliamKong94/p/10961925.html