1. 程式人生 > 其它 >函式物件,名稱空間,閉包函式

函式物件,名稱空間,閉包函式

函式物件

函式是第一類物件,函式是第一等公民

1、函式可以被賦值
# def foo():  # foo->函式的記憶體地址
#     print('from foo')
#
# f=foo
# # print(f)
# f()

2、函式可以當作引數傳給另外一個函式
# def foo():  # foo->函式的記憶體地址
#     print('from foo')
#
# def func(f):
#     # print(f)
#     f()
#
# func(foo)

3、函式可以當作函式的返回值
# def foo():  # foo->函式的記憶體地址
#     print('from foo')
#
# def func(f):
#     return f
#
# res=func(foo)
# print(res)

4、函式可以當作容器型別的元素
# def foo():  # foo->函式的記憶體地址
#     print('from foo')

# l = [foo]

# print(l)
# l[0]()
def login():
    print('登入'.center(50, "*"))


def register():
    print('註冊'.center(50, "*"))


def withdraw():
    print('提現'.center(50, "*"))


def transfer():
    print('轉賬'.center(50, "*"))


func_dic = {
    "1": ["登入", login],
    "2": ["註冊", register],
    "3": ["提現", withdraw],
    "4": ["轉賬", transfer],
}
while True:
    print("0    退出")
    for i in func_dic:
        print("%s    %s" % (i, func_dic[i][0]))

    choice = input("請輸入命令編號:").strip()
    if choice == "0":
        break
    if choice in func_dic:
        func_dic[choice][1]()
    else:
        print("命令編號錯誤,重新輸入")

函式巢狀

函式巢狀呼叫

在呼叫一個函式的過程中,該函式內部又呼叫了其他函式

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


 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(113,133,122,312)
函式的巢狀定義:在函式內又定義了其他函式-------->封閉
# def foo():
#     def bar():
#         print('from bar')
#
#     # bar()
#     x = 111
# foo()
#
# # bar()
# print(x)

園的周長與面積
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)

res = circle(30,1)
print(res)

名稱空間Namespace

存放名字與記憶體地址繫結關係的地方

內建名稱空間:放的是python自帶的名字,print\len\input
#            生命週期:直譯器啟動則產生,直譯器關閉則銷燬
# 全域性名稱空間:放的是頂級的名字,如下x\y\foo
#            生命週期:執行python檔案則立即產生,python檔案執行完畢則結束
# x = 111
#
# if 10 > 3:
#     y = 666
#
# def foo():
#     z = 222
# 區域性名稱空間:放的是函式內的名字,如上z
#            生命週期:呼叫函式則產生,函式呼叫完畢則銷燬
# 重要結論1: 名字的查詢優先順序
#           區域性-》全域性-》內建
#           基於自己當前所在的位置向外查詢,LEGB
# len = 100
#
# def foo():
#     len = 200
#
# foo()
#
# print(len)
# 重要結論2: 名稱空間的巢狀關係是以函式定義為準生成的,與呼叫位置無關
# 例1
# def foo():
#     print(len)
#
#
# def bar():
#     len = 666
#     foo()
#
# len = 100
#
# bar()


# # 例2;
# x = 111
#
#
# def f1():
#     print(x)
#     x = 222
#
#
# f1()


# # 例3
#
# x = 1
#
# def f1():
#      x = 2
#     def f2():
#          x = 3
#         print(x)
#     f2()
#
# f1()

global關鍵字

在函式內,無論巢狀多少層,都可以檢視到全域性作用域的名字

# # 例1:
# x = 1
# def foo():
#     global x
#     x = 2
#
# foo()
# print(x)

# 例2:
# x = [111,222,333]
# def foo():
#     x.append(4444)
# foo()
# print(x)

nonlocal關鍵字

宣告一個名字是來自於外層函式,如果外層沒有不會找到全域性,會報錯

# x = 1
# def f1():
#     x = 2
#     def f2():
#         # global x
#         nonlocal x
#         x = 3
#     f2()
#     print(x)
#
# f1()
# 全域性作用域:全域性存活,全域性有效
#            內建名稱空間,全域性名稱空間
# 區域性作用域:臨時存活,區域性有效
#            區域性名稱空間

閉包函式

閉包函式=函式物件+函式巢狀定義+名稱空間與作用域
閉函式:定義在函式內部的函式
# 包函式: 內部函式引用了一個外層函式的名字
# def foo():
#     x = 111
#     def wrapper():
#         print(x)
#
#     return wrapper  # 千萬不要加括號
#
#
# f = foo()
#
#
# # print(f)
#
# def xxx():
#     x = 222
#     f()
#
# xxx()
閉包的函式的作用:閉包函式是一種為函式體傳參的方案
# 為函式體傳參方案一:直接使用形參
# def wrapper(x):
#     print(x)
#
# wrapper(111)
# wrapper(222)
# wrapper(333)
# 為函式體傳參方案二:閉包函式

# def outter(x):
#     # x = 111

#     def wrapper():   (先從這開始推)
#         print(x)

#     return wrapper
#
#(全域性變數,不同於區域性) wrapper = outter(111)
# wrapper()
#
# # wrapper = outter(222)
# # wrapper()