Python函數(shù)作用域


函數(shù)返回值

  • 省略return語句的情況下默認: return None
  • 可以有多個return語句,但是只會執(zhí)行其中一個
  • 函數(shù)不能同時返回多個值
    • return 1,2,3:表示返回一個元祖

參數(shù)作用域

  • 全局作用域:在整個程序運行環(huán)境中都可見
  • 局部作用域:在函數(shù)、類內(nèi)部可見,使用范圍不超過其所在的局部作用域
  • Eclosing: 嵌套函數(shù)的外層函數(shù)的作用域

參數(shù)訪問規(guī)矩

  • 外層作用域中的變量在內(nèi)層作用域中可見
  • 內(nèi)層作用域中的變量在外層作用域中不可見
  • 內(nèi)層作用域中重新定義同名變量,不會影響外層中的變量
  • 參數(shù)訪問限制突破
    1. 全局變量關(guān)鍵字global:參數(shù)的作用范圍包括全局作用域以及當前作用域
      • 在全局作用域中必須有設(shè)定的參數(shù)
      • 在當前函數(shù)的局部作用域中修改參數(shù),也會直接對全局變量修改
      • 作用域不會影響到嵌套的函數(shù)內(nèi)部
    2. 自由變量關(guān)鍵字nonlocal:變量定義為自由變量
      • 聲明變量定義在當前作用域的上一層局部作用域中
      • 變量只能是局部作用域的,不能是全局作用域

自由變量與閉包

  • 自由變量:未在本地作用域中定義的非全局變量

    • 只會出現(xiàn)在函數(shù)嵌套結(jié)構(gòu)中
  • 閉包定義:

    • 閉包是一種函數(shù),它會保留定義函數(shù)時存在的自由變量的綁定,這樣調(diào)用函數(shù)時,雖然定義作用域不可用了,但是仍能使用那些綁定
  • 閉包特點:

    • 內(nèi)層函數(shù)引用了外層函數(shù)作用域的自由變量
    • 只能出現(xiàn)在函數(shù)嵌套結(jié)構(gòu)中
    • 是一個包含了函數(shù)和引用自由變量的代碼塊
    • 引用自由變量的值被保存在函數(shù)對象的closure屬性中(地址)
  • 函數(shù)對象的code屬性中保存局部變量和自由變量的名稱

    • code.co_varnames: 局部變量名稱
    • code.co_freevars: 自由變量名稱(與closure對應(yīng))

默認(缺?。┲祬?shù)

默認值定義在當前作用域中

  • Python中函數(shù)也是對象,參數(shù)默認(缺?。┲荡娣旁?strong>defaults屬性中
    • 默認值會構(gòu)成一個元祖結(jié)構(gòu)
    • 函數(shù)的生命周期內(nèi),屬性會一直存在(多次調(diào)用出現(xiàn)默認值累積現(xiàn)象)
    • 如果默認值是引用類型,可能會引起默認值的變化
  • key類型的參數(shù)默認值存放在kwdefaults屬性中
    • 默認值會構(gòu)成字典結(jié)構(gòu)
  • 實參為引用類型數(shù)據(jù)
    • 實參內(nèi)容不可被修改:使用影子拷貝
      • 要使用修改后的數(shù)據(jù),將影子拷貝變量作為返回值返回
    • 實參內(nèi)容需要被修改:將該參數(shù)傳給位置參數(shù)
      • 形參使用None缺省值
      • 根據(jù)實參值類型選擇新建列表還是直接修改列表

全局函數(shù)銷毀

  • 函數(shù)也是對象,可以使用del函數(shù)來刪除標示符
  • 定義同名函數(shù),即可作廢上一個函數(shù)
  • 程序結(jié)束時,函數(shù)可銷毀

局部函數(shù)銷毀

  • 在上級函數(shù)中定義同名函數(shù)
  • 使用del語句來銷毀函數(shù)
  • 上級作用域銷毀時,函數(shù)銷毀

作用域栗子

def add(d):
    def _add():
        d = d + 1
        print(d)
    print(d)
  • 上述代碼執(zhí)行時拋出異常:引用了未定義的變量
  • L75(左邊的d),在編譯函數(shù)的定義體時:定義了d為局部變量(字節(jié)碼可看)
  • 在執(zhí)行d+1的表達式時,會在局部作用域中查找,發(fā)現(xiàn)d沒有賦值,拋出異常
  • 賦值語句的執(zhí)行順序是:先右后左
add = logger(add)  #裝飾器語法
  • 上面代碼不會報錯,因為在編譯函數(shù)的定義體時,定義了add對象的作用域
  • 在執(zhí)行l(wèi)ogger(add)表達式的時候,在當前的作用域中可以找到add對象
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容