python全域性變數、區域性變數&類屬性、例項屬性
阿新 • • 發佈:2018-11-09
由於這幾個變數比較容易混淆,下面總結一下。
全域性變數:
在一個py檔案或者一個模組或者包中,但不在類中、不在函式內中的變數。
區域性變數
在函式內、在class的方法內(未加self修飾),這就是區域性變數
靜態變數/類變數
在class內的,但不在class的方法內的,這就是靜態變數/類變數(並且作為類被匯入時,類變數是被初始化的)
例項變數
在class的方法內的,用self修飾的變數,這就是例項變數
看個例子:
global_a = 1
class MyClass:
class_a = 2 # 類變數
def __init__(self) :
self.a = 3 # 例項變數
a = 4 # 區域性變數
def sum(self):
global global_a # 函式內定義global_a變數,使用global來宣告全域性變數
global_a += 1
return global_a
c = MyClass()
1、全域性變數與區域性變數
global_a # 1
c.global_a # 例項c訪問不到區域性變數
Traceback (most recent call last):
File "<input>" , line 1, in <module>
AttributeError: 'MyClass' object has no attribute 'global_a'
c.sum() # 2 由於類函式內使用global關鍵字來宣告global_a,因此可以繼承使用全域性變數
global_a # 2 全域性變數值被更新
2、類變數與例項變數(屬性)
dir(c) # 內建函式dir()取出例項c擁有的類屬性,和自己的例項屬性
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__' , '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'class_a', 'sum']
c.__dict__ # __dict__定義個例項屬性集,以key-value返回例項變數名稱及值(vars(c)同樣)
{'a': 3}
c.class_a # 2
c.a # 3
下面看下例項屬性試圖更改類屬性的情況:
c.class_a = 666
c.class_a # 666 # 例項c只是更改了自己屬性集中的class_a的value值,覆蓋了類中繼承來的class_a屬性
MyClass.class_a # 2 # 類屬性不會改變
但是如果類屬性可變,情況就不同了:
class C:
x = {'a': 111}
c = C()
c.x # {'a': 111}
c.x.update({'b': 222})
c.x # {'a': 111, 'b': 222} 例項c的屬性集更新
C.x # {'a': 111, 'b': 222} 類的屬性字典x也被更新了
總結:
1、全域性變數,類可以直接訪問,函式內必須使用global關鍵字才可以訪問全域性變數
2、類屬性和例項屬性分別擁有自己的屬性集,類屬性更改會影響到所有例項,例項屬性的更改,只是寫入例項屬性集,不影響類屬性(但是可變類屬性除外)。