1. 程式人生 > >python全域性變數、區域性變數&類屬性、例項屬性

python全域性變數、區域性變數&類屬性、例項屬性

由於這幾個變數比較容易混淆,下面總結一下。

全域性變數:
在一個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、類屬性和例項屬性分別擁有自己的屬性集,類屬性更改會影響到所有例項,例項屬性的更改,只是寫入例項屬性集,不影響類屬性(但是可變類屬性除外)。