2011-10-03 25 views
-2

我expet此代碼應輸出:引用在Python類自我

但事實並非如此。

class tree: 
    def __init__(self, size=2): 
     if size == 0: 
      return None 
     if size > 1: 
      half = size//2 
      self.left = tree(size-half) 
      self.right = tree(half) 
     else: 
      self.left = self.right = None 
     self.free = size 
     self.size = size 

    def resize(self,n): 
     while self.size < n: 
      t = tree(0) 
      t.left = self 
      t.right = tree(self.size) 
      t.free = t.left.size + t.right.size 
      t.size = self.size * 2 
      self = t 
     print("size in resize", self.size) 

t = tree() 
t.resize(5) 
print("size of t", t.size) 

輸出:

size in resize 8 
size of t 2 

我知道我可以在主做resizereturn selft = tree.resize(5),但如果我想返回別的什麼?

+3

請不要......修改'self'。請注意,這*只是*「命名」一個對象 - 「給一個名爲'self'的本地變量賦值」 - 它可以*永遠不會「改變」對象本身或引用該對象的外部變量。這個問題是遞歸和*返回新值的一個很好的選擇。 – 2011-10-03 22:41:11

+0

代碼包含一個拼寫錯誤 - 'self-rigt'而不是'self.right'。 – phooji

+0

但是對象是通過引用傳遞的,或者我如何通過引用傳遞對象的引用? –

回答

4

卡爾的答案對任何事情都是完全正確的,但肯定有一種方法可以使resize按照您的期望行事。

三個步驟:

  1. 充分利用樹的副本
  2. 重新初始化樹,以便它是下一個規模較大的
  3. 將放大樹的left原來的樹

    的副本
    def resize(self,n): 
         while self.size < n: 
          new = self.copy() 
          self.__init__(int(round(self.size, 2)) * 2) 
          self.left = new 
    
         print("size in resize",self.size) 
    
    def copy(self): 
         new = tree(1) 
         new.left = self.left 
         new.right = self.right 
         new.size = self.size 
         new.free = self.free 
         return new 
    

基本上,你牛逼試圖向後做 - 替換self並重新使用self代替self.left,而不是替換self.left並重新使用self

+0

如果我的C++經驗是任何指導,添加'swap'方法也可能派上用場。 BTW,IIRC,方法名稱'copy'實際上由'copy'模塊專門處理。 :) –

+0

@KarlKnechtel根據文檔,它使用'__copy__'和'__deepcopy__'。 – agf

2

self = t

這不,和不能被改寫爲,做你想做的。有什麼都沒有「特殊」關於名稱self在Python中;它就像任何其他變量一樣(事實上,你必須明確地將它傳遞給方法應該是你的第一個提示,與將this作爲關鍵字的語言不同,應該是你的第一個提示;)),並像所有其他變量它具有引用語義。

self = t手段「從該點向前(直到另一個重新定義或範圍的端部),self不再是指什麼self參數稱爲,而是到t指值」。

而且,你有一個錯字在你__init__方法(「rigt」)一個情況下,我認爲free節點的數量應該是不變的類似size - occupied;在這種情況下,計算佔用的節點並使用方法或屬性計算空閒的節點會更清晰,而不是在每次修改時都嘗試更新該計數。 (此外,你似乎試圖做的是各種非pythonic。特別是,具有特定「分配大小」的容器的想法是奇怪的;這種事情通常只對你需要一棵二叉樹用來做什麼?另外,這種方法根本不會平衡這棵樹,如果沒有一個節點存儲任何數據,樹有什麼用?)