2014-09-30 54 views
1

我現在必須學習Python。我應該經常創建一個類來指示python中的類型嗎?

我覺得它與真正完全相反的強類型語言,如OCaml和Java,並且類型的東西在很大程度上被淡化。

例如,當我讀取某人的代碼時,我不知道輸入是什麼,輸出是什麼。有時候,它可能是一個字典列表,其值是一個字典,其值又是一個列表。

我所要做的就是運行它並打印出來,然後我知道。

我還沒有習慣這個。

  1. 如何習慣這個?
  2. 我應該創建一些類來指示類型嗎?
  3. 什麼是一般規則?
+4

這是你的[鴨子打字](http://en.wikipedia.org/wiki/Duck_typing)。通常的方法是:良好的函數文檔,描述性變量名稱和大量的單元測試 – wim 2014-09-30 10:01:52

回答

1

試着專注於你想要的代碼,不要擔心類型。這是一個列表嗎?或者它是否包含在列表中的一些自定義類?如果你需要迭代它,那麼你實際上不需要知道現在。你關心的內容不是容器的細節。所以Python提供迭代,它允許你這樣做:如果你想看看如果事情是in一些容器比你可以使用

for each in stuff: 
    do_something(each) 

同理:

if something in stuff: 
    do_something(stuff) 
    # or perhaps in some other cases: 
    something.some_method() 
    # or 
    stuff.do_it_with(something) 

...並沒有關係」無論東西是列表,集合,字典,元組,SQL查詢結果集,DBM映射(索引文件)等,這些都是實現細節。

當你有一個對象時,你會關心它是否實現了你試圖調用的語義。對象是否爲是某種類型的......或者它是某種類型的代理還是包裝某種類型的實例......或者提供相同功能的某種替代類型......在Python中,所有這些都被視爲無關緊要。如果它提供了這些方法(它保證了所需的語義),然後調用它們。如果您需要處理對象不支持所需方法的可能性,請將該調用包裝在異常處理程序中(try: ... except ...)。我認爲我的代碼可能看起來毫無意義,它是有效的代碼;但是你的問題足夠抽象,以至於很難給出一個有意義的例子。我要說的是,Python編碼允許你專注於語義而不是類型/轉換細節)。

+0

我認爲你的答案中描述的優勢似乎是好的代碼作家,但不是讀者?我的意思是,例如,對於'stuff.do_it_with(something)',如果我拿走你的代碼並且不知道什麼是東西或什麼東西,我唯一能做的就是嘗試,如果失敗,我會找出原因。這是範例嗎? – 2014-09-30 12:35:42

+0

閱讀Python代碼時,您通常要關注正在實現的語義而不是所涉及的類型。當試圖理解足夠的代碼來修改代碼時,你必須回溯到類/類型,以便調查任何其他方法(以及如你所說的返回值)。最簡單的方法通常是啓動iPython(或者只是Python解釋器)......實例化適當類的對象,並使用自省來查看它的方法和iPython的? (幫助)魔術或'pydoc'和你的瀏覽器來閱讀它的文檔。 – 2014-09-30 17:46:08

1

評論,文檔字符串和doc測試在幫助您確定函數作爲輸入/輸出所期望的內容方面發揮了重要作用。 Python 3也有添加類型註解,這是不用於通過解釋什麼,但極大的幫助讀者:

 
def find_key_max(d:dict): 
    return max(d.keys()) 

def find_value_max(d:dict): 
    return max(d.values()) 

只是通過給函數有用的名稱,添加類型標註我做了它相當清楚這些是什麼函數做。評論會更有幫助:

def find_key_max(d:dict): 
    """Finds the largest key in the dictionary d""" 
    return max(d.keys()) 

當然,這隻適用於輸入參數的類型真的很重要的情況。 Python的神奇之處在於,通常確切的類型並不重要。如果我在上面的方法中傳遞了list而不是字典,則錯誤消息將清楚地說明問題所在。用簡單的煙霧測試很容易發現這樣的錯誤。另外,很多程序員(包括我自己)都覺得他們不需要編譯器看着他們的肩膀,告訴他們我是否可以調用MyObject.my_method。如果我願意,我會盡我所能編譯器!相信我,我知道我在做什麼。這種理念使您能夠更快地編寫代碼,因爲您不必爲取悅編譯器而努力。如果有東西像鴨子一樣呱呱叫(它有一個quack方法),那麼它的類型是Duck。我不在乎編譯器是否認爲它是Chicken類型,它嘎嘎聲,因此會完成這項工作。

+0

這是一個* docstring * - 不是註釋:) – 2014-09-30 10:09:22

+0

嗯,它也是一個註釋,因爲它不是可執行代碼。但我認爲你的觀點:) – mbatchkarov 2014-09-30 10:13:28

+1

呃...評論沒有得到通過解析階段,所以不可用於字節碼,而docstrings可以綁定到適當的方法和稍後檢索文檔字符串/文檔工具等。 ..我會說他們是相當不同:) – 2014-09-30 10:16:54

0

如果你真的需要知道它是什麼類型,如果你想強制特定類型的輸入使用isinstance方法

if isinstance(variable, int): 
    # Do integer stuff here 

交替進行。

def my_funciton(in): 
    assert isinstance(in, int), "in is not an integer!" 

我建議你一如既往地記錄一切。

def my_function(in): 
    """calculate some result. 

    Args: 
     in (int): This is an integer input 

    Return: 
     (int): the input variable multiplied by 2 
    """ 
    return in*2 
# end my_function 

有很多不同的方法來在Python中記錄代碼。我建議你找到與獅身人面像兼容的東西。有幾個獅身人面像插件可用於不同的風格。

相關問題