python基礎:函式名稱空間、作用域、全域性變數和區域性變數
一、名稱空間:
Python的名稱空間的本質是一個字典,用來記錄變數名稱和值。字典的key是變數的名稱,字典的value對於的是變數的值。
例如 {‘name’:’zs’,’age’:10}
名稱空間一共分為三種:區域性名稱空間、全域性名稱空間、內建名稱空間
區域性名稱空間:
每個函式都有自己的名稱空間,叫做區域性空間,它記錄了函式的變數,包括函式的引數 和區域性定義的變數
全域性名稱空間:
每個模組擁有它自已的名稱空間,叫做全域性名稱空間,它記錄了模組的變數,包括函式、 類、其它匯入的模組。
內建名稱空間:
任何模組均可訪問它,它存放著內建的函式和異常。
input,print,str,list,tuple…
c=10
def func():
a=10
b=20
#{'a':10,'b':20}
#func() #記憶體地址(),函式名本質就是記憶體地址()來呼叫方法
func1=func #把func記憶體地址賦值給func1
print(func)
# 區域性變數:{‘a’:10,‘b’:20}
# 全域性變數:{‘c’:10,‘func’:’<function func at 0x00000000004C2E18>(func對應的記憶體地址)’}
# 內建名稱空間:紀錄的是內建函式:例如:print(),id(),type().... # {'print':'記憶體地址','id';'記憶體地址'}
1、訪問名稱空間的內容:
使用locals()內建函式來檢視區域性名稱空間中的內容
使用globals()內建函式來檢視全域性名稱空間的內容
注意:
如果locals()沒有在函式體中,而是在py檔案中,打印出來的內容和
glabals()相同。
d = 30
def func(c):
a = 10
b = 20
print(locals())
# {'b': 20, 'a': 10, 'c': 30}
func(30)
print(globals())
print(locals())
執行結果:
{'b': 20, 'a': 10, 'c': 30} {'__name__': '__main__', '__doc__': '\n1、使用locals()內建函式來檢視區域性名稱空間中的內容\n2、使用globals()內建函式來檢視全域性名稱空間的內容\n\n注意:\n如果locals()沒有在函式體中,而是在py檔案中,打印出來的內容和\nglabals()相同。\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000000000063D080>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/homework/pythonworksplace/day08/demon02-訪問名稱空間中的內容.py', '__cached__': None, 'func': <function func at 0x00000000005C2E18>}
2、名稱空間的載入順序
內建名稱空間(程式執行前載入)->全域性名稱空間(程式執行中:從上到下載入)->區域性名稱空間(程式執行中:呼叫時才載入)當函式返回結果 或 丟擲異常時,被刪除。每一個遞迴呼叫的函式都擁有自己的名稱空間。
內建名稱空間>全域性名稱空間>區域性名稱空間
a = 10
b = 20
def func():
c = 20
print(c)
func()
print(a)
print(b)
執行結果:
20
10
20
3、名稱空間的查詢順序
當使用某個變數的時候,先從區域性名稱空間中找,如果能找到則停止搜尋,如果找不到在去全域性名稱空間中查詢,如果找到則停止搜尋,如果找不到則到內建名稱空間中查詢,如果找不到則報錯。
(1)名稱空間的順序:
區域性名稱空間 全域性名稱空間 內建名稱空間
先從區域性名稱空間這種查詢,如果能查詢到,則停止搜尋,
如果找不到就去全域性名稱空間中查詢,如果找到停止搜尋,
如果找不到就去內建名稱空間中查詢,如果找到就返回內容,
如果找不到,就報錯
(2)如果一開始就從全域性名稱空間中查詢,就直接找全域性名稱空間中的內容
如果找到則停止搜尋,如果找不到就從內建空間中查詢。
(3)注意事項:
自己的變數名稱不要和內建的變數名相同,否則不能使用內建名稱空間中的函式功能。
def func():
id = 20
print(id
func()
print(id)
執行結果:
20
<built-in function id>
注意事項:自己的變數名不要個內建名稱空間中的函式名相同。
否則無法使用內建函式功能。
# a = 10
# id = 20
# print(id(a)) #報錯
巢狀函式的情況:
1、先在當前 (巢狀的或 lambda) 函式的名稱空間中搜索
2、然後是在父函式的名稱空間中搜索
3、接著是模組名稱空間中搜索
4、最後在內建名稱空間中搜索
二、作用域:
1、作用域:指的是變數的可用範圍
2、根據變數宣告的位置不同,作用可分為4類:
區域性作用域---->函式體中宣告的變數
巢狀作用域---->巢狀函式中外層函式體中宣告的變數
全域性作用域---->py檔案中宣告的作用域
內建作用域---->python提供的變數(函式)
3、變數的搜尋順序:
先從當前作用域查詢,如果找到則停止搜尋,如果找不到,就往
上一層作用域中查詢。依次類推,如果找不到就報錯。
b=20 #b變數宣告在了全域性作用域,因此可以在全域性作用域使用
def func():
a=10
#a變數在區域性作用域中
#a變數的作用範圍就是整個函式體
print(a)
print(b) #可以作用在區域性作用域中
func()
# print(a) #報錯,因為a變數已經出了自己的作用域範圍。
print(b) #可以正常執行
c=30
def outter():
a=10
def inner():
b=20
print(b)
print(c)#訪問全域性作用域中的內容 #30
print(a)#訪問巢狀作用域的內容 #10
#print(b) #報錯,b出了自己的範圍,巢狀作用域範圍無法訪問區域性作用域範圍的變數
inner()
outter()
print(c) #30 #全域性作用域範圍訪問全域性作用域範圍
#print(a) #報錯,全域性作用域範圍不能訪問巢狀作用域範圍內的變數
變數的搜尋順序:
a=1
def outter():
a=10
def inner():
a=20
print(a) #20.10.1
inner()
print(a) #10,1
outter()
print(a) #1
三、全域性變數和區域性變數
在函式中定義的變數稱為區域性變數,只在函式內部生效,
在程式一開始定義的變數稱為全域性變數,全域性變數的作用域是整個程式。
全域性變數:在函式中定義的變數稱為區域性變數,只在函式內部生效.
區域性變數:在程式一開始定義的變數稱為全域性變數,全域性變數的作用域是整個程式.
name='zs' #全域性變數
def func():
name='ls' #區域性變數
print(name) #ls
func()
a=10
lst=[12,3]
def func(c,lst1):
c=20
lst1.append(4)
print(c,lst1)
func(a,lst)
print(a,lst)
執行結果:
20 [12, 3, 4]
10 [12, 3, 4]
global:關鍵字可以將區域性變數變成一個全域性變數。
nonlocal:關鍵字只能修改巢狀外層(非全域性)變數。
global關鍵字:
a = 10
print(id(a))
def func():
global a # 變成了全域性變數
a = 20 # 修改全域性變數的值
print(id(a)) # id 相同
print(a)
func()
print(a)
執行結果:
505900656
20
20
nonlocal關鍵字:
def outter():
name='zs'
def inner():
nonlocal name #和outter中的name是同一個變數
name='趙四'
print(name) #趙四
inner()
print(name) #趙四
outter()
yunxingjieg:
趙四
趙四
四、名稱空間和作用域的關係
名稱空間定義了在某個作用域內變數名和繫結值之間的對應關係,名稱空間是鍵值對的集合,變數名與值是一一對應關係。作用域定義了名稱空間中的變數能夠在多大範圍內起作用。