2012-01-31 14 views
17

我想盡可能準確地計算多文件Python項目中的代碼行,但不包括註釋,文檔字符串或空白行。如何統計Python中的代碼行(不包括註釋和文檔字符串)?

我第一次嘗試使用cloc,它可以作爲Debian軟件包。但是cloc將大多數文檔視爲代碼 - 儘管它們是評論。 (更新:不再 - CLOC現在把Python的文檔字符串作爲註釋的最新版本)

我注意到下面說的文檔字符串應該包含在總,因爲他們可能會被代碼被用於在影響行爲的一些意見運行時間,因此作爲程序代碼/數據/配置的一部分。一個突出的例子就是'層',它要求你用文本串編寫函數,正如我記得的那樣,它包含語法和正則表達式,它們是程序運行的核心。但是,這在我看來是非常罕見的例外。大多數時候文檔行爲就像評論一樣。具體來說,我知道所有我想測量的代碼都是如此。所以我想排除他們從我的行數。

+19

我想說計數意見_is權way_,因爲一般__the意見是一樣的實際代碼lines__ – Kimvais 2012-01-31 08:45:19

+3

@Kimvais我必須說,我有相反的經驗寶貴20年的編程 - 評論通常毫無價值,因爲編譯器從不檢查它們:-) – 2012-01-31 08:47:07

+7

Python docstrings *是* code - 它們成爲函數的'__doc__'屬性並且可以包含測試。也許你需要通過'代碼行'來定義你的意思 – Hamish 2012-01-31 08:48:26

回答

6

將Python文檔字符串包含在「代碼行數」中可能是正確的。正常情況下,評論會被編譯器丟棄,但文檔字符串被解析:

PEP 257 - Docstring Conventions

文檔字符串是一個字符串字面量出現在 首先聲明一個模塊,函數,類,或方法定義。這樣的文檔字符串變成該對象的特殊屬性。

...

字符串字面發生在Python代碼的其他地方也可作爲 文檔。 它們不是由Python字節碼編譯器可識別 並沒有運行時對象屬性訪問..

換句話說,文檔字符串編譯和構成,在一個非常現實的方式,的代碼程序。另外,它們通常被doctest module用於單元測試,作爲命令行實用程序的使用字符串等等。

+3

不同意。雖然docstrings被編譯並且可以被代碼使用,但它們的使用和語義就像註釋一樣。他們應該被排除在任何有意義的行數之外。 – 2014-02-03 10:07:37

+3

@JonathanHartley個人我認爲「編譯並且可以被代碼使用」是一個很好的論點,因爲它被計算在內。 – Hamish 2014-02-09 20:07:21

+0

嘿。我想我感覺相反,因爲即使它們可以被代碼使用,它們也幾乎不會。我的意思是說,是的,他們被'pydoc'等人使用,但我認爲我看到的唯一一個將數據存儲在文檔中然後檢查數據的程序是David Beazley的'Ply'。所以這是非常罕見的。如果您比較兩個模塊以查看哪些代碼包含更多代碼,並且其中一個包含文檔字符串,但另一個沒有,則排除文檔字符串並獲得結果「它們大致相同」似乎對我非常有用。 – 2014-02-10 10:31:19

2

你有沒有看着http://www.ohloh.net/p/ohcount - 一向相當的錢,我 - 雖然我不使用Python

+2

謝謝,但像cloc這個工具也計算與三撇號作爲代碼docstrings,所以它也不是真正的Python -知道的。 – ifischer 2012-01-31 08:51:52

6

註釋行可以在Python代碼行。例如,請參閱doctest

此外,你將有麻煩找一個合理的/可靠的方法來考慮這樣的情況下,作爲一個評論或代碼:

foo = ('spam', 
     '''eggs 
      eggs 
      eggs''' 
     '''more spam''', 
     'spam') 

只是算註釋行,以及,我想大多數程序員會對於你實際想要測量的任何事物而言,它都是一種很好的衡量標準。

+2

不同意。雖然技術上的文檔編寫和代碼可以訪問,但其使用和語義的巨大優勢是一個評論。他們應該排除行數。在這個答案中檢測模糊的外觀案例的方法是使用AST進行行計數。 – 2014-02-03 10:06:30

4

Tahar不計算文檔字符串。下面是它的count_loc功能:

def count_loc(lines): 
    nb_lines = 0 
    docstring = False 
    for line in lines: 
     line = line.strip() 

     if line == "" \ 
      or line.startswith("#") \ 
      or docstring and not (line.startswith('"""') or line.startswith("'''"))\ 
      or (line.startswith("'''") and line.endswith("'''") and len(line) >3) \ 
      or (line.startswith('"""') and line.endswith('"""') and len(line) >3) : 
      continue 

     # this is either a starting or ending docstring 
     elif line.startswith('"""') or line.startswith("'''"): 
      docstring = not docstring 
      continue 

     else: 
      nb_lines += 1 

    return nb_lines 
+6

非常感謝您提供合理的建議,並且不要像您的同事一樣,對文檔作爲代碼進行荒謬而認真的聲明。代碼行是一個有效的代碼複雜度(實際上是最好的:http://herraiz.org/blog/2010/11/22/making-software-is-out/),當我需要這種複雜性來反映原始的源代碼(而不是我在docstrings中大量的_math_筆記),我需要省略docstrings! – 2013-02-19 14:18:46

+3

我相信docstrings中的文檔是用於文檔 – ychaouche 2013-06-23 20:42:08

+0

上面的代碼在使用單引號的文檔字符串或使用三引號的某些常規字符串上會失敗。解決這個問題的正確方法是看AST。 – 2014-02-03 10:09:30

相關問題