2012-08-12 49 views
2

我正在寫一個Python腳本來解析一些數據。此刻,我正在嘗試創建一個創建「佔位符」對象的類。我打算反覆傳遞每個「佔位符」變量,最後將它變成一個字典,浮點,列表或字符串。由於需要一段時間才能描述的原因,如果我可以通過調用方法來替換實例,那將會容易得多。用實例方法中的float替換實例?

這裏有一個簡單的例子

class Event(dict): 

    def __init__(self): 

     self.sumA = 0.0 
     self.sumB = 0.0 

    def augmentA(self, i): 

     self.sumA += i 

    def augmentB(self, i): 

     self.sumB += i 

    def seal(self): 

     if self.sumA != 0 and self.sumB != 0: 
      self = [ sumA, sumB ] 

     elif self.sumA != 0: 
      self = float(sumA) 

     elif self.sumB != 0: 
      self = float(sumB) 

而我想要做的是:

e = Event() 
e.augmentA(1) 
e.augmentA(2) 
e.seal() 

...並有 'E' 轉成浮動。

我所希望避免的是:

e = Event() 
e.augmentA(1) 
e.augmentA(2) 
e = e.getSealedValue() 

我完全明白「自我」在我的「密封」方法僅僅是一個局部變量,並且不會對實例的任何影響外部範圍。但我不確定如何實現我想要的內容,從實例中,對於我的代碼來說最方便。我也明白我可以覆蓋所有的插件(getItem,toStr),但這使我的代碼變得複雜了很多。

我是一個Python noob,所以我不確定這是否可能。放縱我,請:)

+0

對於無聊的問題,我表示歉意,順便說一句,我完全理解* that *視角的觀點。雖然我不明白投票「關閉」!這是一個通用的問題,但不容易通過閱讀文檔來回答 - 我使用的代碼在這裏,因爲不使用代碼很難解釋。 – username 2012-08-12 04:47:57

+0

我不能說誰投票決定關閉它,但它看起來像是一個寫得很好的建設性問題,所以我只是假設某人心情不好,並且沒有仔細閱讀這個問題或仔細閱讀這個問題幫助改善它。 ;-) – Jordan 2012-08-12 05:04:52

+0

廢話,現在因爲我的抱怨而上升。停下來! Downvotes很好,可能是有保證的,請不要關閉它 – username 2012-08-12 05:07:45

回答

2

在某些情況下,Python允許您即時更改對象的類。然而,並非任何對象可以轉換爲任何類,如下面的例子演示了(換行增加了可讀性):

>>> class A(object): 
... pass 
... 
>>> class B(object): 
... pass 
... 
>>> a = A() 
>>> type(a) 
<class '__main__.A'> 

>>> a.__class__ = B 
>>> type(a) 
<class '__main__.B'> 

>>> a.__class__ = int 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: __class__ assignment: only for heap types 

(我不知道從我頭頂的確切規則,但如果你的班級使用__slots__,例如它們必須兼容才能進行轉換)

然而,正如其他答覆者指出的那樣,通常這是一個非常糟糕的主意,即使有辦法將每個對象的引用轉換爲對另一個對象的引用。我不會去從來沒有這樣做,但是,這種技術可能有合法的用途(例如,我認爲這是一種實現State Design Pattern而不會產生不必要的混亂的簡單方法)。

+0

這很有幫助。我發現「class assignment」錯誤在python.or上也被描述爲「對象佈局不同」,因此我將嘗試更改我的「密封」方法以刪除與目標Class不同的任何成員/方法。如果它有效,如果創建第二個實例的時候我並沒有真正看到我的程序拋出錯誤的缺點,當我僅僅創建一個實例時 - 如果有的話,它是免費的更嚴格的錯誤檢查,不是?此外,「狀態設計」鏈接很有幫助 - 我需要更仔細地閱讀它 – username 2012-08-12 06:53:57

+0

更正:如果創建第二個*引用* – username 2012-08-12 07:17:26

2

不,你不能有一個變量值通過調用它的方法取代自己。正常的做法是這樣的:e = e.getSealedValue()

你可以做一個對象改變的行爲,但這通常被認爲是一個壞主意,並可能導致高度不可維護的代碼。

+1

1.你可以通過調用它的方法來完全改變一個對象的行爲(儘管這是一個壞主意)2.'e = ..'不能代替對象。它將名稱「e」綁定到另一個對象。 – jfs 2012-08-12 05:24:31

2

即使有一些理智的方式,使其工作,我會避免走這條路,只是因爲它改變了對象的類型的東西與現有的合同完全不符。

現在,人們可以說「但我只在一個地方使用它,其他代碼路徑永遠不會看到舊的合同」,但不幸的是,這不是這個機制的一個參數,因爲你只能簡單地一旦擁有最終對象,就可以爲其他代碼路徑提供該值。

總之,不要這樣做,甚至不要嘗試。