2015-11-17 129 views
2

我們說classes在Python中是可變的,這意味着您可以使用引用來更改將在對象中反映的值。例如,爲什麼我不能在Python中更改類的屬性

>>> A = [1, 2, 3] 
>>> B = A 
>>> B[2] = 5 
>>> A 
[1, 2, 5] 

在這裏,我可以更改使用BA對象的值,因爲list是一個可變的類型。我的問題是,爲什麼我不能改變使用以下相同的概念類的屬性:

class C: 

    apple = 2 

    def __init__(self): 
     self.dangerous = 2 

D = C# D is pointing to same class C 

D().dangerous = 5 # changing the value of class attribute D 

D().apple = 3 # changing the value of apple here 

print D().apple 

print D().dangerous 

OUTPUT: 
2 
2 

任何人都可以解釋爲什麼輸出22但不35,因爲我們都在講類是mutable類型。

UPDATE:通過@ zxq9參考答案,如果你看到下面的圖做D=C時,D實際上是指向同一類,而一個新的對象,你所描述。你能解釋這一點:

enter image description here

+1

在世界上有什麼人downvoting用的? OP問了一個非常明確的問題,就是沒有意識到實例化對象和類定義之間的語法差異。 – zxq9

+0

@ zxq9你能看到我更新的圖片嗎? – python

+1

是的,但*你仍然只分配給類的臨時實例*而不是類本身。我會玩弄這個,並擴大我的答案以覆蓋這一點。用Python來記住它是一件非常好的事情。 – zxq9

回答

6

每次你把括號類之後,你正在構建類的新的實例對象。所以你打印的東西是全新的品牌,並沒有反映你以前做過的短期任務。

下面是一個例子(擴大到覆蓋下面的參考C類):

>>> class C: 
... red = 2 
... def __init__(self): 
...  self.blue = 2 
... 
>>> C.red 
2 
>>> C.blue 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: type object 'C' has no attribute 'blue' 
>>> C().red 
2 
>>> C().blue 
2 
>>> #OOOOH! 
... 
>>> z = C() 
>>> z.red 
2 
>>> z.blue 
2 
>>> D = C 
>>> D.red 
2 
>>> D().red 
2 
>>> D().red = "over 9000!" 
>>> D.red 
2 
>>> D.red = "No, really over 9000!" 
>>> D.red 
'No, really over 9000!' 
>>> C.red 
'No, really over 9000!' 
>>> #OOOOOOHHHH! 
... 

請注意,我們更改類直接當我分配C.apple = 3 - 因爲被引用類定義本身,而不是從它創建的實例化對象。

通過精心的示例代碼走,注意參考ClassName調用ClassName()之間的差異。第一個是參考通過一個變量名到一個類定義 - 生成實例對象的藍圖,它帶有一個構造函數__init__()。第二個是調用__init__(),它的返回值是定義它的類的實例對象。

這也是爲什麼你可以做這樣的事情:

def some_fun(another_fun, value): 
    another_fun(value) 

def foo(v): 
    return v + v 

def bar(v): 
    return v * v 

some_fun(foo, 5) 
some_fun(bar, 5) 

此功能借給Python中的高度靈活性在建築功能的抽象。 (現在,如果只有尾巴消除......)

+0

概念清除:)謝謝 – python

0

這是一個有趣的例子。

  1. d()危險= 5將改變的屬性 「危險」 的實例d的()。但行打印D()。危險打印出屬性「危險」的另一個實例D()
  2. d()。蘋果= 3在實例d()因爲這種情況下不具有屬性「蘋果」創建屬性「蘋果」。
  3. 打印d()。蘋果將打印出的類d的屬性「蘋果」,因爲實例d()沒有屬性「蘋果」。通過實例來改變類的屬性「蘋果」
  4. 一種方式是通過使用d().__類__。蘋果= 3
相關問題