函數嵌套及做用域

1、函數對象閉包

函數是第一類對象:函數的內存地址(即函數名)能夠像一個變量值同樣去使用ide

一、變量值能夠被引用,例如 x = 1,y = x函數

def foo(): print('from foo') f = foo     # 變量值(函數名)被引用
print(f) f()

二、變量值能夠看成參數傳給另一個函數url

def foo(): print('from foo') def bar(x): print(x) x() bar(foo) # 函數名看成參數傳給另一個函數

三、變量值能夠看成函數的返回值spa

def foo(): print('from foo') def func(x): return x f = func(foo)   # 函數名看成函數的返回值
print(f)

四、變量值能夠看成容器類型的元素code

def foo(): print('from foo') li = [foo, ]    # 函數名看成列表的元素
print(li) li[0]() dic = {'1': foo}   # 函數名看成字典的元素
print(dic) dic['1']()

2、函數嵌套對象

一、函數的嵌套定義:在函數內又定義了其餘函數blog

def func(): def foo(): print('from foo') foo() x = 1
    print(x) func()

二、函數嵌套調用:在一個函數內部又調用其餘函數內存

# 比較四個數的大小
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(1, 2, 3, 4))
# 計算圓的面積和周長

from math import pi def circle(radius, action): def cal_perimeter(): return 2 * pi * radius def cal_area(): return pi * (radius ** 2) if action == 1: res = cal_perimeter() elif action == 2: res = cal_area() return res res = circle(5, 1) print(res)
計算圓的面積和周長

3、名稱空間ci

一、定義:存放名字與值的內存地址綁定關係的地方

二、名稱空間分爲三大類:

  內置名稱空間:存放的是 Python 解釋器自帶的名字,Python 解釋器的啓動則產生,關閉則銷燬

  全局名稱空間:建立的存儲 「變量名與值的關係」 的空間,是在頂級定義的,Python程序執行時產生,程序執行完畢後則銷燬

  局部名稱空間:在函數的運行中開闢的臨時的空間,是在函數內部定義的,在函數調用時臨時產生,調用完畢後則銷燬

三種名稱空間的加載順序和取值順序:

加載順序:內置(程序運行前加載)-->全局(從上到下順序加載進來的)-->局部(調用的時候加載)--->內置

取值:

  當前在局部名稱空間:局部 ---> 全局 ---> 內置

  當前在全局名稱空間:全局 ---> 內置

使用:全局不能使用局部的,局部的可使用全局的

4、做用域:就是做用範圍

一、全局做用域

定義:包含內置與全局名稱空間的名字

特色:在整個程序的任意位置都能被引用,全局有效

二、局部做用域

定義:包含局部名稱空間的名字

特色:臨時存活,只能在局部範圍內生效

做用域關係是在函數定義階段就已經固定死了,與調用位置無關!!

# 示範一:
def f1(): print(xxx) xxx = 111

def f2(): xxx = 222
    # 無論f1在哪調用, 都是去找定義階段的做用域關係,
    # 與上面的xxx=222沒有任何關係
 f1() f2() # 執行結果:111
# 示範二:
xxx = 111
def f1(): ''' 函數定義階段只檢測語法, 不執行代碼 這裏先輸出xxx, 先從局部找xxx, 找到了x=222可是卻定義在了輸出的下面 語法上這種寫法是錯誤的 '''
    print(xxx) xxx = 222 f1() # 執行結果報錯

5、閉包函數

閉:封閉,指的是該函數定義一個內部函數

包:該內部函數包含了對外層函數做用域中變量的引用 

def outter(): x = 1
    def inner(): print("from inner", x) return inner f = outter()    # 經過外部函數拿到了內部函數的地址

def foo(): print(f) f() foo()

爲函數體傳值的兩種方式:

  def foo():

    print('hello %s' %name)

方式一:直接以參數的形式傳入

def foo(name): print("hello %s" %name) foo('qiu') foo('qiu') foo('qiu')

這種方式要想屢次傳值,每次都要手動添加參數

方式二:閉包含數

def outter(name): def foo(): print("hello %s" %name) return foo f = outter('qiu') f() f() f()

要想屢次傳值只須要屢次調用函數便可

 

應用:獲取一個網頁的信息

# 解決方案一: 以參數的形式傳入

def get(url): response = requests.get(url) if response.status_code == 200: print(response.text) # 要想屢次獲取信息只能屢次傳入
get('https://www.baidu.com') get('https://www.cnblogs.com')
# 解決方案二: 閉包函數無需屢次傳入

def outter(url):
    def get(): response = requests.get(url) if response.status_code == 200: print(response.text) return get baidu = outter('https://www.baidu.com') cnblogs = outter('https://www.cnblogs.com') # 要想屢次獲取只需屢次調用
baidu() baidu() cnblogs()
相關文章
相關標籤/搜索