函数对象、函数嵌套以及名称空间与作用域

函数对象、函数嵌套以及名称空间与作用域

一 函数对象

1 函数对象是什么

​ 函数对象指的是函数可以被当成变量去使用。

def foo():
    print('from foo')
print(foo)  # <function foo at 0x00000215D4F95F70>
# 函数名就是一个内存地址

2 函数对象如何使用

2.1 函数对象可以被赋值

f = foo
print(f is foo)  # True
f()  # from foo

2.2 函数对象可以当作参数传给一个函数

def bar(func):
    print(func) 
    func()

bar(foo)  # <function foo at 0x0000014936EE5EE0>
          # from foo

2.3 函数对象可以当成函数的返回值

def bar(func):
    return func

res = bar(foo)
print(res)  # <function foo at 0x000001FEF84C5EE0>

2.4 函数对象可以当成容器类型的一个元素

l = [foo]
print(l)  # [<function foo at 0x0000023FB8685F70>]
l[0]()  # from foo
# 示例:
def login():
    print('登录功能')

def register():
    print('注册功能')

def transfer():
    print('转账功能')

def charge():
    print('充值')

def withdraw():
    print('提现')

func = {
    "1": ("登录",login),
    "2": ("注册",register),
    "3": ("转账",transfer),
    "4": ("充值",charge),
    "5": ("提现",withdraw)
}

while True:
    print("0 退出")
    for k,v in func.items():
        print(k,v[0])
    choice = input("请输入你的操作编号:").strip()
    if choice == "0":
        break
    if choice in func:
        func[choice][1]()
    else:
        print("输入的指令不存在")

二 函数嵌套

1 函数嵌套的定义及特点

### 1.定义
​		函数嵌套就是一个函数在运行是调用了另一个函数。
def bar():
    print('from bar')
    
def foo():
    print('from foo')
	bar()

foo()  # from foo
       # from bar    
### 2.特点
​		正常情况下只能在函数体内部被调用。
# 案例:
from math import pi


def circle(radius, mode=0):
    def perimiter(radius):
        return 2 * pi * radius

    def area(radius):
        return pi * (radius ** 2)

    if mode == 0:
        return perimiter(radius)
    elif mode == 1:
        return area(radius)


res1 = circle(3, 0)
res2 = circle(3, 1)
print(res1)
print(res2)

2 函数嵌套的调用

def bar():
    print('from bar')
    
def foo():
    print('from foo')
	bar()

foo()  # from foo
       # from bar
# 案例: 
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)
    print(res3)


max4(1, 2, 3, 4)

三 名称空间与作用域

1 名称空间

		名称空间就是存放名字与对象映射关系的地方。在python程序运行的时候有三种名称空间。

1.1 内置名称空间及其生命周期:

		存放python内置名字的地方。

​		生命周期:解释器启动时产生,解释器关闭则消失。

1.2 全局名称空间及其生命周期:

		存放顶级名字的地方。

​		生命周期:python程序运行时产生,python程序结束时销毁。
# foo = 内存地址
def foo():  # foo本身也是全局的
    z = 111

    # f1 = 内存地址 
    def f1():  # f1是属于局部的
        pass

if True:    # if语句是全局的
    aaa = 33

1.3 局部名称空间及其生命周期:

		存放函数内部名字的地方。

​		生命周期:调用函数时产生,调用结束时销毁。

1.3 名字查找的优先级:

		从当前位置往外查找,如果当前在局部:局部名称空间——》全局名称空间——》内置名称空间。

​		从当前位置往外查找,如果当前在全局:全局名称空间——》内置名称空间。

1.5 注意:嵌套关系的确定阶段

		名称空间的嵌套关系,是在函数定义阶段就确定的,与函数的调用位置无关。
x = 111

def f1():
    print(x)

def f2():
    x = 222
    f1()

f2()  # 111

# 示范5:

def f3():

    print(x)
    x = 33333

x=222
f3()   # UnboundLocalError: local variable 'x' referenced before assignment
# 定义函数的时候,print(x)中x是局部作用域中的x,但是在调用的时候,x还没定义,也不能向上查找,所以报错,无法执行。

2 作用域

2.1 全局范围/全局作用域及其特点:

		全局作用域 = 内置名称空间 + 全局名称空间。

​		特点:全局存活,全局有效。

2.2 局部范围/局部作用域及其特点:

		局部作用域 = 局部名称空间

​		特点:临时存活,局部有效。

2.3 了解global与nonlocal

#### (1) global
​		global就是声明变量是全局作用域下的变量。
x = 10


def func():
    global x
    x = 22


func()
print(x)  # 22
#### (2) nonlocal
​		nonlocal就是声明变量是来自局部作用域下的外层函数。
x = 10

def f1():
    x = 111

    def f2():
        nonlocal x
        x = 222		# nonlocal之后,把外层函数的x改成了222,所以调用f1()打印出来的是f2

    f2()
    print(x)  
    
f1()    # 222
posted @ 2020-03-11 20:28  越关山  阅读(418)  评论(0)    收藏  举报