国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

淺談python函數之作用域(python3.5)

2020-01-04 16:24:12
字體:
來源:轉載
供稿:網友

1 基本概念

1.1 命名空間 (namespace)

命名空間是變量名到對象的映射(name -> obj)。目前大多數的命名空間以類似于python字典的形式實現,實現形式在未來可能發生變化。命名空間舉例:內置變量(內置函數abs, 內置的異常等),模塊中的全局變量,函數調用時的局部變量。在某種意義上講,對象的屬性也形成一個命名空間。重要的是,不同的命名空間中的變量沒有任何關聯,兩個不同的命名空間中可以包含相同的變量名。

命名空間有不同的創建時間和生命周期:

•內置變量命名空間在python解釋器啟動時創建,并且在解釋器運行期間永遠不會被刪除;

•一個模塊的命名空間在模塊被導入時創建,并且到解釋器退出會一直存在;

•函數的本地(局部)命名空間在函數調用時創建,函數退出時刪除;

•解釋器頂層執行的語句都是 __main__ 模塊的組成部分,它們有自己的命名空間。

注:內置變量實際上同樣是以模塊的形式存在,模塊名為 builtins 。

1.2 作用域 (scope)

作用域是Python程序中可以直接訪問一個命名空間內變量的文本區域,可直接訪問即命名空間內的變量在該文本區域內可見、可引用。

•本地(局部)作用域:函數或者類的內部

•全局作用域:整個程序的運行環境。

全局作用域中無法直接訪問本地作用域中定義的變量:

def func1(): name = 1print(func1) # <function func1 at 0x101a03d08>print(name)# Traceback (most recent call last):# File "<stdin>", line 1, in <module># NameError: name 'name' is not defined

本地作用域中的變量定義:

•在python中,變量賦值即定義。在局部作用域內被賦值的變量,除非由 global 或者 nonlocal 聲明,否則全部為局部變量,函數調用時存在于函數命名空間。

•global var : 聲明變量 var 為全局變量,它所有的引用和賦值都在模塊的命名空間進行。

•nonlocal var : 將外層函數命名空間中的變量 var 綁定到本地作用域,使其在本地作用域可重新賦值。如果變量沒有被聲明為 nonlocal,這些變量在本地作用域僅可讀,嘗試給變量賦值則會在本地命名空間創建一個同名變量。

nonlocal聲明的變量在上層函數中必須存在,否則報錯:

test = 'global variable'def scope_test(): def inner():  nonlocal test  print(test)scope_test() # SyntaxError: no binding for nonlocal 'test' found

2 示例

2.1 本地作用域中變量的搜索遵守LEGB規則

1.L-Local(function):函數或類的命名空間,其中的變量稱為本地變量

2.E-Enclosing function locals:外層函數的命名空間(例如closure),包含被聲明為non-local的變量

3.G-Global(module):函數定義所在模塊的命名空間,其中的變量稱為全局變量

4.B-Builtin(Python):Python內置模塊的名字空間

def scope_test(): def do_local():  spam = "local spam" def do_nonlocal():   nonlocal spam  # 遞歸向上尋找上層函數命名空間中的spam變量  spam = "nonlocal spam" def do_global():  global spam # 在全局變量中尋找spam變量,沒有則創建  spam = "global spam" spam = "test spam" do_local() print("After local assignment:", spam) # 輸出本地變量 spam do_nonlocal() print("After nonlocal assignment:", spam) do_global() print("After global assignment:", spam)scope_test()print("In global scope:", spam)

結果

<SPAN style="FONT-SIZE: 14px">1 After local assignment: test spam After nonlocal assignment: nonlocal spam After global assignment: nonlocal spam In global scope: global spam </SPAN>

2.2 閉包

閉包:在嵌套函數中,如果內層函數引用了外層函數的變量,就形成了一個閉包。

自由變量:被引用的外層函數變量,稱為內層函數的自由變量。

def fn():  a = 1  def closure():    nonlocal a    a += 1    print(a)  return closureinner = fn() print(inner.__closure__)  # (<cell at 0x10240b408: int object at 0x100277bc0>,)inner() # 2inner() # 3

外層函數執行完,其命名空間刪除。但是因為 a 是內層函數的自由變量,所以變量 a 被保留,可以看作是 closure 函數對象的一個附加屬性。

3 靜態檢測

3.1 本地變量

python是在編譯def語句時靜態檢測其本地變量的。

a = 1def local_test():  a += 1  print(a)local_test()  # UnboundLocalError: local variable 'a' referenced before assignmentprint(b)  # NameError: name 'b' is not defined

在編譯local_test函數時,python就確定了變量 a 為函數的本地變量。所以在執行 a += 1 是會直接在本地命名空間尋找變量a。

3.2 命名空間搜索鏈

name = "lzl" def f1():  print(name) def f2():  name = "eric"  f1() f2() # lzl

一個函數的變量搜索路徑是在它定義的時候決定的,不受它調用位置的影響。

f1定義在全局作用域中,其變量的搜索路徑為:本地命名空間 --> 模塊命名空間。所以最后的輸出結果為‘lzl'。

4 匿名函數

Python借助lambda關鍵字定義匿名函數,格式如下:

lambda 參數列表: 表達式

lambda x: x + 1# 函數功能類型于下面的函數def _(x):  return x + 1

示例

下面一段代碼的輸出結果是什么:

li = [lambda :x for x in range(10)]print(li[0]())

其等價形式:

def fn():  return x li = []for x in range(10):  li.append(fn)li[0]() # fn() -> 9,根據變量搜索規則,x在函數中沒有定義,在全局變量中查找

以上這篇淺談python函數之作用域(python3.5)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到python教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 龙里县| 栖霞市| 永宁县| 高邮市| 塔城市| 全州县| 奎屯市| 南丹县| 玛沁县| 顺昌县| 东乡族自治县| 云阳县| 永嘉县| 四子王旗| 清原| 朝阳县| 都江堰市| 海门市| 商河县| 永川市| 大关县| 抚顺市| 陆川县| 德化县| 鄂州市| 灌云县| 堆龙德庆县| 勃利县| 台中市| 肇源县| 台中县| 永兴县| 河曲县| 丘北县| 开阳县| 成安县| 女性| 泊头市| 玛曲县| 涪陵区| 延吉市|