2013-02-03 106 views
2

這不是我正在處理的任何東西,它只是一些測試代碼,因爲我只是在學習類方法和吸吮。但說我有下面的代碼Python類方法改變自我

class Test(int): 
    def __init__(self,arg): 
      self = arg 

    def thing(self): 
      self += 10 

去, 富=測試(12)設置FOO到12但是我想它,所以當我這樣做,foo.thing(),由10 FOO增加。到目前爲止,去foo.thing()只是保持在12.我將如何改變這個代碼來做到這一點。

+0

賦值'self = arg'對新的'foo'實例沒有任何作用(它重新賦值'self',它不更新'int'子類實例)。改用'__new__'方法;你可以安全地忽略'__init__'。 –

+0

'int'是不可變的,你不能神奇地把它變成一個可變類。 –

回答

4

因爲int是不可變的,所以不能神奇地將它變成可變類型。

你的方法是禁用的。他們在本地命名空間中更改self,將其重新分配給其他內容。他們不再指出實例。換句話說,兩種方法都保留原始實例不變的

你不能對int的子類做什麼。您必須改用numeric type hooks來重新創建一個自定義類。

背景:int具有__new__方法,該方法的實際值分配給self,並且沒有__iadd__方法就地加入到支持。 __init__方法不會被忽略,但您可以將它完全放棄,因爲__new__已經完成了這項工作。

分配到self意味着你剛剛更換用別的東西的參考實例,你沒有改變任何關於self

>>> class Foo(int): 
...  def __init__(self, value=0): 
...   print self, type(self) 
...   self = 'foobar' 
...   print type(self) 
... 
>>> foo = Foo(10) 
10 <class '__main__.Foo'> 
<type 'str'> 
>>> print foo, type(foo) 
10 <class '__main__.Foo'> 

因爲int沒有就地一個__iadd__添加方法,您的self += 2被解釋爲self = self + 2,而不是;再次,您將分配給self並將其替換爲新的值。

+0

我明白了。所以它只適用於像list和類似的東西?所以如果我想要一個修改它的函數,我不得不這樣稱呼它嗎? foo = foo.dostuff()並且只是讓dostuff方法返回一個新值 –

+1

@GregHornby:不,你需要在方法'dostuff()'內賦值給'self'的* attributes *或者調用方法* on *'self',而不是分配給'self'本身。 –

+0

完全如此;但是'int'對象恐怕沒有這樣的屬性。 –