2011-08-10 52 views
3

背景:我有一個模擬寄存器的類,該芯片有一堆寄存器,其中一個是內置溫度傳感器的高溫極限。在Python中使用單位變量

我有以下幾點:

class foo(): 
    def __init__(self): 
    # does not set self._hiTemp! 
    ... 
    def setHiTemp(self, t): 
    self._hiTemp = t 
    def getHiTemp(self): 
    return self._hiTemp 
    def checkHiTemp(self): 
    return self._temp > self._hiTemp 

,我不聲明self._hiTemp__init__是因爲用戶可能不關心芯片的溫度檢測功能的原因。用戶可以以不同的方式使用該芯片,並且給這個變量賦予無意義的價值沒有意義。但是,如果用戶在未首先設置的情況下嘗試使用self._hiTemp,那麼使用未聲明的變量的錯誤比調用/回溯(比較數字和無)(或者在某些情況下甚至根本沒有錯誤)等一些模糊錯誤更容易調試/回溯。

這一切都很順利,直到我開始pylint,當然我得到W0201:屬性定義init幾乎無處不在。我只是想知道這種編碼方式是否被忽視,如果是的話,那麼「Pythonic方式」是什麼。

感謝

+2

'self._hiTemp = None' – JBernardo

+0

我會存儲這些特性,感覺對我來說更清潔。 – leoluk

+1

@leoluk什麼是字典讓你在這裏?像Python這樣的動態語言的美妙之處在於,首先所有的對象都基本上都是美化詞典。另請參見'self。\ _ \ _ dict \ _ \ _' –

回答

11

我這樣做的方式是將其設置爲None或其他一些不會「自然」發生的哨兵值。然後,對於需要設置的操作,如果主叫方嘗試不適當地使用您的對象,請使用assert快速失敗。

def __init__(self): 
    self._hiTemp = None 

def checkHiTemp(self): 
    assert self._hiTemp is not None, 'Why you no set _hiTemp before checking it?' 
    return self._temp > self._hiTemp 
+0

使用'assert'是錯誤的,因爲它可以在運行時使用'-O'或'-OO'標誌進行優化。正確的方法是引發一個例外,如下面的@ John-La-Rooy所示。 –

0

這是習慣使用的值None意味着沒有真正的價值。您可以將其初始化爲__init__。在這種情況下,您可能也會使用無意義的值(如負數),並在checkHiTemp方法中檢查該值,並在未使用正確初始化值的情況下引發自定義異常。這是一個更有意義的錯誤。

0

我認爲從用戶的角度來看,最好是有一個正確的錯誤消息比未聲明的變量錯誤。我會做:

def __init__(self): 
    self._hiTemp = None 

def setHiTemp(self, t): 
    self._hiTemp = t 

def getHitemp(self): 
    if self._hiTemp is None: 
     raise Exception('You need to setHiTemp() before using it.') 
    else: 
     return self._hiTemp 

def checkHiTemp(self): 
    if self._hiTemp is None: 
     raise Exception('You need to setHiTemp() before using it.') 
    else: 
     return self._temp > self._hiTemp 
+0

yeap,你完全正確。最好將它改爲「如果self._hiTemp不是None:」。 =) – Kenji

+0

我猜想像「HiTemp沒有設置」比「foo實例沒有屬性_hiTemp'」更隱蔽。雖然,我可能會引發AttributeError或NameError,而不是僅僅基於異常=) –

1

如果你希望對象的特定屬性通過的方法進行設置,那麼可能永遠原因是在初始化可用。您可以使用self._hiTemp=None您已通過領導_將其聲明爲私有,因此用戶將理解爲不依賴於此。

4

Python不是Java,所以不要寫這樣的getter和setter。你能解決你的問題像代替實例屬性字典這個

class Foo(object): 
    def __init__(self, hiTemp=None): 
     self._hiTemp = hiTemp 

    @property 
    def hiTemp(self): 
     if self._hiTemp is None: 
      raise AttributeError("You have not initialized hiTemp") 
     return self._hiTemp 

    @hiTemp.setter 
    def hiTemp(self, value): 
     self._hiTemp = value 

    def checkHiTemp(self): 
     return self._temp > self._hiTemp 

foo=Foo() 
foo.hiTemp = 50 
print foo.hiTemp # Prints 50 

foo=Foo(hiTemp=20) 
print foo.hiTemp # Prints 20 

foo=Foo() 
print foo.hiTemp # Raises exception 
+0

感謝您的建議,我可以使用屬性(我在我的代碼中的大多數地方),但他們仍然本質上是setters和getters。關於未初始化函數處理方式的問題仍然存在。 –

+0

@ paper.cut,是的,但是關鍵的區別是,在Python中,我可以使用屬性訪問,直到找到我需要的getter或setter,然後我只需要在類中更改代碼。我不需要到處重構代碼。我不確定爲什麼你更喜歡喬的答案 - 這種方式的工作原理是相同的,但是測試是自動完成的,所以我不需要記住每次訪問屬性時都要重複測試 –

+0

雖然你的答案也很好,但是屬性不是我要求的。我知道屬性是如何工作的,而且我正在使用它們,只是針對這個問題,我特別提出了有關初始化變量的問題,因此我將其簡化爲不使用屬性。 –