網站首頁 編程語言 正文
Python是靜態作用域語言,但是它自身是一個動態語言。在Python中變量的作用域是由變量在代碼中的位置決定的,與C語言有些相似,但不是完全一樣。
在Python 2.0及之前的版本中,Python只支持3種作用域,即局部作用域,全局作用域,內置作用域;在Python
2.2中,Python正式引入了一種新的作用域 — 嵌套作用域;嵌套作用域的引入,本質上為Python實現了對閉包的支持。
1、簡單介紹一下閉包
def test(): A = 3 B = 4 def stu(): C = 3 return A+B+C return stu stu = test() stu
在上述此代碼中stu方法定義在test的內部,內部函數stu即可以使用外部函數test的變量,我們稱這種行為叫做閉包。
2、在Python中,并不是任何代碼塊都能引入新的作用域
Python中不是任何代碼塊都可以引入新的作用域這與C有很大的不同:
在C中:
#includeint main() { if(2 > 0) { int i = 0; } printf("i = %d", i); return 0; }
在上述代碼中,if子句引入了一個局部作用域,變量i就存在于這個局部作用域中,但對外不可見,因此,接下來在printf函數中對變量i的引用會引發編譯錯誤。
但是,在Python中卻并非如此:
if True: i = 0 print i
在上述代碼中,if子句并沒有引入一個局部作用域,變量i仍然處在全局作用域中,因此,變量i對于接下來的print語句是可見的。
實際上,在Python中,只有模塊,類以及函數才會引入新的作用域,其它的代碼塊是不會引入新的作用域的。
在Python中,使用一個變量之前不必預先聲明它,但是在真正使用它之前,它必須已經綁定到某個對象;而名字綁定將在當前作用域中引入新的變量,同時屏蔽外層作用域中的同名變量,不論這個名字綁定發生在當前作用域中的哪個位置。
>>> f() Traceback (most recent call last): File "", line 1, in File " ", line 2, in f NameError: name 'i' is not defined >>>
運行結果報錯:
NameError: name ‘i’ is not defined
程序運行時,Python首先在函數f的本地作用域中查找變量i,查找失敗,接著在全局作用域和內置作用域中查找變量i,仍然失敗,最終拋出NameError異常。
>>> def f(): ... i = 8 ... print(i) ... >>> f() 8 >>> print(i) 0 >>>
運行結果顯示:
8和0
i = 8是一個名字綁定操作,它在函數f的局部作用域中引入了新的變量i,屏蔽了全局變量i,因此f內部的print語句看到的是局部變量i,f外部的print語句看到的是全局變量i。
>>> i = 0 >>> def f(): ... print(i) ... i = 0 ... >>> f() Traceback (most recent call last): File "", line 1, in File " ", line 2, in f UnboundLocalError: local variable 'i' referenced before assignment >>>
運行結果報錯:
UnboundLocalError: local variable ‘i’ referenced before assignment
在上述中,函數f中的變量i是局部變量,但是在print語句使用它的時候,它還未被綁定到任何對象之上,所以拋出異常。
3、在Python中,名字綁定在所屬作用域中引入新的變量,同時綁定到一個對象。
名字綁定發生在以下幾種情況之下:
- 參數聲明:參數聲明在函數的局部作用域中引入新的變量;
- 賦值操作:對一個變量進行初次賦值會在當前作用域中引入新的變量,后續賦值操作則會重新綁定該變量;
- 類和函數定義:類和函數定義將類名和函數名作為變量引入當前作用域,類體和函數體將形成另外一個作用域;
- import語句:import語句在當前作用域中引入新的變量,一般是在全局作用域;
- for語句:for語句在當前作用域中引入新的變量(循環變量);
- except語句:except語句在當前作用域中引入新的變量(異常對象);
總結
原文鏈接:https://blog.csdn.net/qq_45691220/article/details/123354446
相關推薦
- 2022-06-01 AutoMapper實體映射基本用法_實用技巧
- 2022-06-06 Kafka在Zookeeper中存儲的信息有哪些?
- 2022-06-16 Kotlin操作符重載實例詳解_Android
- 2022-04-15 C語言?指針數組進階詳解_C 語言
- 2022-09-26 Redis刪除策略的三種方法及逐出算法_Redis
- 2022-08-21 如何使用C語言將數字、字符等數據寫入、輸出到文本文件中_C 語言
- 2022-05-11 剖析數據庫中重要而又常被曲解的概念
- 2022-08-17 React自定義hook的方法_React
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支