變量進階
目標
變量的應用
可變和不可變類型
局部變量和全局變量
01.變量的應用
變量和數據都是保存在內存中的
在Python中函數的參數傳遞以及返回值都是靠引用傳遞的
1.1引用的概念
在Python中
變量和數據是分開存儲的
數據保存在內存中的一個位置
變量中保存著數據在內存中的地址
變量中記錄數據的地址,就叫做引用
註意:如果變量已經被定義,當給一個變量賦值的時候,本質上是修改了數據的應用
變量不再對之前的數據引用
變量改為對新賦值的數據引用
1.3 函數的參數和返回值的傳遞
在Python中,函數的實參/返回值都是靠引用來傳遞的
# 函數實參的引用傳遞
def test(num):print("在函數內部 %d 對應的內存地址是 %d" % (num,id(num))) # 1.定義一個數字的變量 a = 10 # 數據的地址本質上就是一個數字 print("a 變量保存數據的內存地址是 %d" % id(a)) # 2.調用test函數 本質上傳遞的是實參保存數據的引用,而不是實參保存的數據 test(a)
函數返回值的傳遞
def test(num): print("在函數內部 %d 對應的內存地址是 %d" % (num,id(num))) # 1> 定義一個字符串變量 result = "hello" print("函數要返回數據的內存地址是 %d" % id(result)) # 2> 將字符串變量返回,返回的是數據的引用,而不是數據本身 return result # 1.定義一個數字的變量 a = 10 # 數據的地址本質上就是一個數字 print("a 變量保存數據的內存地址是 %d" % id(a)) # 2.調用test函數 本質上傳遞的是實參保存數據的引用,而不是實參保存的數據 # 註意:如果函數有返回值,但是沒有定義變量接收 # 程序不會報錯,但是無法獲得返回結果 r = test(a) print("%s 的內存地址是 %d" % (r,id(r)))
02.可變和不可變類型
不可變類型,內存中的數據不允許被修改:
數字類型 int,bool,float,complex,long(2,x)
字符串 str
元組 tuple
可變類型,內存中的數據可以被修改:
列表 list
字典 dict
註意:字典的key只能使用不可變類型的數據
註意:
1.可變類型的數據變化,是通過方法來實現的
2.如果給一個可變類型的變量,賦值了一個新的數據,引用會修改
變量不再對之前的數據引用
變量改為對新賦值的數據引用
哈希(hash)
Python中內置有一個名字叫做 hash(o)的函數
接收一個不可變類型的數據作為參數
返回結果是一個整數
哈希 是一種算法,其作用就是提取數據的特征碼(類似指紋)
相同的內容得到相同的結果
不同的內容得到不同的結果
在Python中,設置字典的鍵值對時,會首先對key進行hash已決定如何在內存中保存字典的數據,以方便後續對字典的操作:增、刪、改、查
鍵值對的key必須是不可變類型數據
鍵值對的value可以是任意類型的數據
03.局部變量和全局變量
局部變量是在函數內部定義的變量,只能在函數內部使用
全局變量是在函數外部定義的變量(沒有定義在某一個函數內),所有函數內部都可以使用這個變量
提示:在其他的開發語言中,大多不推薦使用全局變量——可變範圍太大,導致程序不好維護!
3.1 局部變量
局部變量是在函數內部定義的變量,只能在函數內部使用
函數執行結束後函數內部的局部變量會被系統回收
不同的函數可以定義相同的名字的局部變量,但是各用個的不會產生影響
局部變量的作用
在函數內部使用,臨時保存函數內部需要使用的數據
def demo1(): # 定義一個局部變量 num = 10 print("在demo1函數內部的變量是 %d" % num) def demo2(): # print("%d" % num) 函數內部定義的變量不能在另一個函數內使用 pass # 在函數內部定義的變量,不能再其他位置使用 # print("%d" % num) 函數內部定義的變量不能在函數外部使用 demo1() demo2()
局部變量的生命周期
# 所謂 生命周期 就是變量從被創建到被系統回收的過程 # 局部變量 在函數執行時才會被創建 # 函數執行結束後 函數變量 被系統回收 # 局部變量在生命周期內,可以用來存儲函數內部臨時使用到的數據
# 1> 出生:執行了下方代碼之後,變量才會被創建
# 2> 死亡:函數執行完成之後,變量會被系統回
3.2 全局變量
全局變量是在函數外部定義的變量,所有的函數內部都可以使用這個變量
# 全局變量 num = 10 def demo1(): print("demo1 ==> %d" % num) def demo2(): print("demo2 ==> %d" % num) demo1() demo2()
註意:函數執行時,需要處理變量時會:
1.首先查找函數內部時候存在指定名稱的局部變量,如果有,直接使用
2.如果沒有,查找函數外部是否存在指定名稱的全局變量,如果有,直接使用
3.如果還沒有,程序報錯!
1)函數不能直接修改全局變量的引用
全局變量是在函數外部定義的變量(沒有定義在某一個函數內),所有函數內部都可以使用這個變量
提示:在其他開發語言中,大多不推薦使用全局變量——可變範圍太大,導致程序不好維護
在函數內部,可以通過全局變量的引用獲取對應的數據
但是,不允許直接修改全局變量的引用——使用賦值語句修改全局變量的值
# 全局變量 num = 10 def demo1(): # 希望修改全局變量的值 # 在Python中,不允許直接修改全局變量的值 # 如果使用賦值語句,會在函數內部,定義一個局部變量 num = 99 print("demo1 ==> %d" % num) def demo2(): print("demo2 ==> %d" % num) demo1() demo2()
# 註意:只有在函數內部定義了一個函數變量而已,只是變量名相同——在函數內部不能直接修改全局變量的值
2)在函數內部修改全局變量的值
如果在函數中需要修改全局變量,需要使用global進行聲明
# 修改全局變量 num = 10 def demo1(): # 希望修改全局變量的值 ——使用global聲明一下變量即可 # 當下面的函數調用到全局變量時,調用的就是在這個函數中修改後的值 global num num = 99 print("demo1 ==> %d" % num) def demo2(): print("demo2 ==> %d" % num) demo1() demo2()
3)全局變量定義的位置
為了保證所有的函數都能夠正確使用到全局變量,應該將全局變量定義在其他函數的上方
# 註意:在開發時,應該把模塊中的所有全局變量 # 定義在所有函數上方,就可以保證所有的函數 # 都能夠正常的訪問到每個全局變量了 num = 10 def demo(): print("%d" % num) print("%s" % title) # print("%s" % name) # 在定義一個全局變量 title = "hmcxy" demo() # 再定義一個全局變量 # name = "xiaoming" 因為該全局變量定義在函數下方, # 導致系統再未定義該變量之前就運行到了函數demo
註意:如果全局變量在調用函數之後才定義,在執行函數時,變量還沒有定義,所以程序會報錯
4)全局變量命名的建議
為了避免局部變量和全局變量出現混淆,在定義全局變量時,有些公司會有一些開發要求,例如:
全局變量名前應該增加g_或者gl_的前綴
提示:具體的要求格式,各公司要求可能會有些差異
gl_num = 10 # 在定義一個全局變量 gl_title = "小明" # 再定義一個全局變量 gl_name = "小王" def demo(): # 如果局部變量的名字和全局變量的名字相同 # pycharm會在局部變量下方顯示一個波浪線 提示可能會產生混淆 num = 99 print("%d" % num) print("%s" % gl_title) print("%s" % gl_name) demo()
當程序中多個相同變量名需要修改時,可以將鼠標防止到需要修改的變量名上,右鍵 refactor rename
變量進階