2009-09-11 46 views
13

我有靜態類型語言的編程經驗。現在用Python編寫代碼,我覺得它的可讀性很困難。可以說,我有一個類主機Python代碼可讀性

class Host(object): 
    def __init__(self, name, network_interface): 
    self.name = name 
    self.network_interface = network_interface 

我不從這個定義理解,什麼叫「NETWORK_INTERFACE」應該是。它是一個字符串,就像「eth0」或它是一個類的實例NetworkInterface?我想要解決這個問題的唯一方法是使用「docstring」來記錄代碼。像這樣的東西:

class Host(object): 
    ''' Attributes: 
     @name: a string 
     @network_interface: an instance of class NetworkInterface''' 

或者可能有這樣的名稱約定?

+2

__init __()的第一個參數應該是self。 – 2009-09-11 09:00:46

+1

@bmm:謝謝(我忘記了) – legesh 2009-09-11 09:05:38

+3

你的意思是說你有使用靜態類型語言的經驗嗎?我問這個問題是因爲Python *是強類型的(1+「hello」引發錯誤)。 – EOL 2009-09-11 11:44:36

回答

21

使用動態語言會教給你一些關於靜態語言的知識:從靜態語言中獲得的所有幫助,你現在在動態語言中都會錯過,但並不是那麼有用。

要使用您的示例,使用靜態語言,您應該知道該參數是一個字符串,而在Python中則不然。所以在Python中你寫了一個文檔字符串。而當你寫這篇文章的時候,你會發現你有更多的話要說,而不是「這是一個字符串」。您需要說明字符串中的數據,以及它應該具有的格式,默認值以及錯誤條件。

然後你意識到你應該爲靜態語言寫下所有的東西。當然,Java會強迫你知道它是一個字符串,但是還有其他所有需要指定的細節,你必須用任何語言手動完成這項工作。

+0

好帖子,我同意這些觀點。 – 2009-09-11 10:47:37

+0

非常有趣,的確! – EOL 2009-09-11 11:46:41

+2

唯一的問題是,我遇到的大多數代碼都沒有評論好,如果有的話:(我一開始也在用python掙扎(想靜態輸入那麼糟糕),但同意一個簡潔的文檔字符串解決了這個問題。 – heavilyinvolved 2010-02-04 18:47:44

10

文檔字符串約定在PEP 257

有以下格式指定參數的例子,你可以,如果他們不管添加類型:

def complex(real=0.0, imag=0.0): 
    """Form a complex number. 

    Keyword arguments: 
    real -- the real part (default 0.0) 
    imag -- the imaginary part (default 0.0) 

    """ 
    if imag == 0.0 and real == 0.0: return complex_zero 
    ... 

也有人支持文檔字符串屬性的拒絕PEP(而非構造函數的參數)。

+0

@Pete Kirkham:感謝PEP的鏈接257 – legesh 2009-09-11 09:16:33

+1

我發現引用的例子過多。例如,默認值是顯而易見的,不需要提及。文檔字符串應該提及的一個示例是,如果None被傳遞,那麼默認爲None的參數將被替換。 – u0b34a0f6ae 2009-09-13 22:51:07

9

最pythonic的解決方案是用例子來記錄。如果可能的話,說明一個對象必須支持哪些操作是可以接受的,而不是特定的類型。

class Host(object): 
    def __init__(self, name, network_interface) 
    """Initialise host with given name and network_interface. 

    network_interface -- must support the same operations as NetworkInterface 

    >>> network_interface = NetworkInterface() 
    >>> host = Host("my_host", network_interface) 

    """ 
    ... 

在這一點上,勾源達doctest,以確保您的文檔的例子在未來繼續合作。

4

我個人發現使用pylint來驗證我的代碼非常有用。

如果你幾乎自動地跟隨pylint的建議你的代碼變得更具可讀性,你會提高你的python寫作技巧,尊重命名約定。您還可以定義自己的命名約定等。這對python初學者特別有用。

我建議你使用。

2

Python雖然不像C或Java那樣顯式地鍵入,但仍然是鍵入的,並且如果您使用的類型完全不能很好地進行匹配,則會引發異常。

爲此,如果您擔心您的代碼被正確使用,正確維護等,只需使用文檔字符串,註釋或甚至更多顯式變量名稱來指示該類型應該是什麼類型。

更好的是,包含代碼將允許它處理可能傳遞的類型,只要它能產生可用的結果。

1

靜態類型的一個好處是類型是一種文檔形式。當用Python進行編程時,您可以更靈活流暢地編寫文檔。當然,在你的例子中,你想說network_interface應該實現NetworkInterface,但是在很多情況下,類型從上下文,變量名或慣例中是顯而易見的,在這些情況下,通過省略顯而易見的,你可以生成更多可讀代碼。常見的是描述參數的含義並隱式給出類型。

例如:

def Bar(foo, count): 
    """Bar the foo the given number of times.""" 
    ... 

這說明簡潔和準確的功能。從上下文來看,foo和bar的含義是顯而易見的,並且count是(正)整數是隱含的。

對於你的榜樣,我剛剛提到在文檔字符串類型:

"""Create a named host on the given NetworkInterface.""" 

這是短,更具可讀性,且包含比類型列表更多信息。