4.10 Python變數
4.10.1 變數介紹
變數,顧名思義,就是可以變化的量,變數的概念基本上和初中代數的方程變數是一致的,只是在計算機程式中,變數不僅可以是數字,還可以是任意資料型別,
Python中的變數不需要宣告,每個變數在使用前都必須賦值,變數賦值以后該變數才會被創建,
在 Python中,變數就是變數,它沒有型別,我們所說的型別是變數所指的記憶體中物件的型別,如果有個資料不被任何變數所指向,則會被Python的回識訓制回收掉,以節省記憶體,
在Python中,一切皆物件,所以其實:變數就是物件的名字!
4.10.2 變數名
變數在程式中需要用變數名進行表示,在Python中,變數的命名是需要滿足一定的條件的:
- 允許包括英文(中文等其他國家文字也可以)、數字以及下劃線_,不能以數字開頭
- 名稱區分大小寫,例如:fun和Fun是不同的變數名,
- 不要使用關鍵字作為變數名,這可能會導致未知的錯誤,
以下是一些變數命名的建議: - 以_開頭的變數是有特殊意義的,最好不要創建以
_開頭的變數名, - 變數命名建議采用駝峰命名法(MyName、UserId)或蛇形命名法(my_name、user_id),
- 特殊變數或者常量建議全部大寫,
- 類名建議使用駝峰命名法,
- 變數名最好要做到見名知意,
4.10.3 變數的賦值
賦值運算子=用來給變數賦值,=左邊是一個變數名,=右邊是存盤在變數中的值,
>>> counter = 100 # 整型變數
>>> miles = 1000.0 # 浮點型變數
>>> name = "atom" # 字串
>>> a = b = c = 1 # 鏈式賦值
>>> a, b, c = 1, 2, 3 # 多個變數同時復制
>>> a, *b, c = 1, 2, 3, 4, 5 # 裝包
>>> a, b = b, a # 交換變數
>>> a, b, c = [1, 2, 3] # 解包賦值
>>> x += 1 # 增強賦值
在Python中,可以把任意資料型別賦值給變數,同一個變數可以反復賦值,而且可以是不同型別的變數,這點和其它編程語言有所不同,因此,Python是一種動態語言,而與之對應的靜態語言在變數賦值時需要先定義變數型別,如果后續賦值時型別和定義時不匹配,就會報錯,
和靜態語言相比,動態語言更加靈活,
讓我們來看看在Python中變數賦值時發生了什么,當我們將atom賦值給name時:
>>> name = 'atom'
Python解釋器會先在記憶體中創建一個atom的字串,然后再創建一個名為name的變數,并指向atom,
我們可以想象有個箱子,里面裝了一個資料,就是字串的atom,而變數就像是一個標簽,標簽名是name,貼在了剛才的箱子上,如果是貼在裝有100數字型別的箱子上,那么這個變數就是100,
在Python中,一定要牢記一點:變數無型別,資料才有型別,變數就是個標簽,貼在什么資料上,就是什么資料型別,下面這個例子能很好的說明這一點:
a = 100
b = a
a = 'string'
print(f'a: {a}')
print(f'b: {b}')
a: string
b: 100
4.10.3.2 Python中表示常量
所謂常量就是不能變的變數,比如常用的數學常數π就是一個常量,在Python中,通常用全部大寫的變數名表示常量:
>>> PI = 3.14
但事實上PI仍然是一個變數,Python根本沒有任何機制保證PI不會被改變,所以,用全部大寫的變數名表示常量只是一個習慣上的用法,
4.10.3.3 淺復制、深復制
前面我們講過可以通過id()函式獲取某個物件的id,這個id對于每個資料都是不同的,如果兩個變數的id一樣,那么則說明這兩個變數指向同一個物件,
a = 'str'
b = [1, 2, 3]
c = {1: [22, 33]}
aa = a
bb = b
cc = c
print(id(a) == id(aa))
print(id(b) == id(bb))
print(id(c) == id(cc))
print(id(c[1]) == id(cc[1]))
True
True
True
True
像上面,通過=進行復制的一般稱為淺復制(比如:aa = a),淺復制后,aa和a這兩個變數其實指向的都是同一個資料,所以具有一樣的id,只要修改了原始資料后,所有通過淺復制指向這個資料的變數的值都會發生變化:
b = [1, 2, 3]
bb = b
b.pop()
print(f'b: {b}')
print(f'bb: {bb}')
b: [1, 2]
bb: [1, 2]
我們可以通過匯入copy模塊中的deepcopy函式來進行深復制,對于不可變資料,比如:元組或字串等,深復制后指向的還是同一個資料,與淺復制沒有區別,但是對于可變資料,比如:串列和字典,深復制后,雖然變數的值還是一樣,但是指向的資料已經不是同一個了,如下:
from copy import deepcopy
a = 'str'
b = [1, 2, 3]
c = {1: [22, 33]}
aaa = deepcopy(a)
bbb = deepcopy(b)
ccc = deepcopy(c)
print(id(a) == id(aaa))
print(id(b) == id(bbb))
print(id(c) == id(ccc))
print(id(c[1]) == id(ccc[1]))
True
False
False
False
深復制后,由于指向的不是相同的資料,于是,修改其中一個變數后,并不會影響到其它變數,如下:
from copy import deepcopy
b = [1, 2, 3]
bb = deepcopy(b)
print(id(b) == id(bb))
b.pop()
print(f'b: {b}')
print(f'bb: {bb}')
False
b: [1, 2]
bb: [1, 2, 3]
4.10.4 變數的作用域
根據變數的作用范圍,可以將變數分為:區域變數和全域變數,
4.10.4.1 區域變數
在函式、類、方法等內部定義的變數,它的作用域也僅限于其定義時的內部,在外部則不能使用,我們將這樣的變數稱為區域變數(Local Variable),
當函式或類被執行時,Python 會為其分配一塊臨時的存盤空間,所有在函式、類中定義的變數,都會存盤在這塊空間中,而在函式、類執行完畢后,這塊臨時存盤空間隨即會被釋放并回收,該空間中存盤的變數自然也就無法再被使用,
def add(a, b):
c = 10
print(c)
print(a+b)
add(1, 2)
print(c)
10
3
Traceback (most recent call last):
File "E:\studypy\tmp.py", line 6, in
print(c)
NameError: name 'c' is not defined
如上,在add函式中定義了一個變數c,并賦值為10,呼叫add函式時是可以正常列印出來c的,但是在函式外面列印則報錯:name 'c' is not defined
正常情況下,在定義的內部結構體中可以獲取和使用區域變數,也可以對區域變數進行修改和洗掉,
如果想要在外部使用內部變數,則需要在變數前面加上關鍵字global進行宣告,宣告該變數是一個全域變數,
def add(a, b):
global c
c = 10
print(c)
print(a + b)
add(1, 2)
print(c)
10
3
10
4.10.4.1.1 locals()函式
通過locals()函式,我們可以得到一個包含當前作用域內所有變數的字典,這里所謂的“當前作用域”指的是,在函式內部呼叫 locals() 函式,會獲得包含所有區域變數的字典;而在全域范圍內呼叫 locals() 函式,其功能和 globals() 函式相同,
注意:
1、locals() 函式回傳的字典中,會默認包含有很多變數,這些都是 Python 主程式內置的,我們暫時不用理會它們,
2、我們無法可以通過修改上面獲得的字典來修改區域變數的值,
def myprint():
name = 'zhangsan'
print(locals()['name'])
locals()['name'] = "lisi"
print(name)
myprint()
zhangsan
zhangsan
4.10.4.1.2 vars(object)函式
vars()函式也是 Python 內置函式,其功能是回傳一個指定 object 物件(對于函式不起作用)范圍內所有變陣列成的字典,如果不傳入object 引數,vars() 和 locals() 的作用完全相同,
name = "Python"
class Demo:
name = "Python 教程"
print(vars(Demo))
print(vars())
{'module': 'main', 'name': 'Python 教程', 'dict': <attribute 'dict' of 'Demo' objects>, 'weakref': <attribute 'weakref' of 'Demo' objects>, 'doc': None}
{'name': 'main', 'doc': None, 'package': None, 'loader': <_frozen_importlib_external.SourceFileLoader object at 0x0000017DD89A7C40>, 'spec': None, 'annotations': {}, 'builtins': <module 'builtins' (built-in)>, 'file': 'E:\studypy\tmp3.py', 'cached': None, 'name': 'Python', 'Demo': <class 'main.Demo'>}
4.10.4.2 全域變數
在模塊內定義的變數稱為全域變數(Global Variable),和區域變數不同,全域變數的默認作用域是整個程式,即全域變數可以在所有函式、類、類方法中直接使用,
c = 5
def add(a, b):
print(f'c: {c}')
print(f'a+b={a + b}')
add(1, 2)
c: 5
a+b=3
globals() 函式為 Python 的內置函式,它可以回傳一個包含全域范圍內所有變數的字典,該字典中的每個鍵值對,鍵為變數名,值為該變數的值,
注意,globals() 函式回傳的字典中,會默認包含有很多變數,這些都是 Python 主程式內置的,我們暫時不用理會它們,
可以看到,通過呼叫 globals() 函式,我們可以得到一個包含所有全域變數的字典,并且,通過該字典,我們還可以訪問指定變數,甚至如果需要,還可以修改它的值,
name = 'zhangsan'
print(globals()['name'])
globals()['name'] = "lisi"
print(name)
從自動化辦公到智能化辦公zhangsan
lisi
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/509475.html
標籤:Python
上一篇:設計模式---享元模式
下一篇:爬蟲高性能相關
