來測試下 2019 你一共寫了多少行代碼?

寫啊寫代碼,2019 你都寫了多少行代碼呢

來測試下 2019 你一共寫了多少行代碼?

自己動手實現一個代碼統計工具

導入所需的庫

這個程序需要用到的庫有:os,time
這兩個庫都是 Python 自帶的,所以我們直接 import 就行

<code>

import

os

import

time/<code>

現在我們已經導入要使用的庫了,可以直接寫代碼了

定義要讀取的文件地址

首先,我們定義一個路徑吧,因為要讀取文件統計代碼行數嘛

<code> 

base_dir

=

'./'

file_lists

= []/<code>
  • base_dir :假設我們讀取的是當前目錄下的目錄 / 文件
  • file_lists:因為我們讀取的文件不止一個,所以使用列表來存儲

指定你要讀取的文件類型

<code>

file_type

= [

'py'

]/<code>

這裡以 Python 文件為例,因為代碼是用 Python 寫的嘛,所以讀取 py 為後綴的文件

遍歷目錄 / 文件

上面我們定義了路徑是 ./ (當前目錄下),文件類型是 py 的,接下來我們需要遍歷一下當前路徑中的文件,代碼如下:

<code> 
 

def

getDir_or_File(base_dir):

global

file_lists

for

parent,dirnames,filenames in os.walk(base_dir):

for

filename in filenames:

file

=

filename.split('.')[-1]

if

file in file_type:

file_lists.append(os.path.join(parent,filename))

/<code>

代碼分析

os.walk(top, topdown=True, οnerrοr=None, followlinks=False):輸出在文件夾中的文件名通過在樹中游走,向上或者向下

  • top :是你所要遍歷的目錄的地址, 返回的是一個三元組(root,dirs,files)。
  • root :所指的是當前正在遍歷的這個文件夾的本身的地址
  • dirs : 是一個 list ,內容是該文件夾中所有的目錄的名字(不包括子目錄)
  • files :同樣是 list , 內容是該文件夾中所有的文件(不包括子目錄)
  • topdown :可選,為 True,則優先遍歷 top 目錄,否則優先遍歷 top 的子目錄(默認為開啟)。如果 topdown 參數為 True,walk 會遍歷top文件夾,與top 文件夾中每一個子目錄。
  • onerror : 可選,需要一個 callable 對象,當 walk 需要異常時,會調用。
  • followlinks : 可選,如果為 True,則會遍歷目錄下的快捷方式(linux 下是軟連接 symbolic link )實際所指的目錄(默認關閉),如果為 False,則優先遍歷 top 的子目錄

這樣講好像不太好理解,我們實踐一下,編寫以下代碼進行測試

<code>import 

os

for

parent, dirnames, filenames

in

os

.walk(

"./"

):

print

(parent)

print

(dirnames)

print

(filenames)/<code>

從圖中可知道改代碼位於 demo 文件夾下

來測試下 2019 你一共寫了多少行代碼?

OK,我們運行一下這個程序

來測試下 2019 你一共寫了多少行代碼?

沒學過 os 庫的朋友可能會有點疑問,為什麼 for 循環那裡要有三個參數?必須的嗎?

<code>

for

parent

,

dirnames

,

filenames

in

os

.walk

(

"./"

):/<code>

是的,是必須的,不信?我們去掉一個參數運行一下,代碼如下:

<code>import 

os

for

parent, filenames

in

os

.walk(

"./"

):

print

(parent)

print

(filenames)/<code>

運行,報錯了

來測試下 2019 你一共寫了多少行代碼?

報錯信息為:ValueError: too many values to unpack (expected 2)
說我們太多值無法解包?(一頭霧水)
我們來看下官方是怎麼解釋的

來測試下 2019 你一共寫了多少行代碼?

對於根目錄在目錄樹頂部的每個目錄(包括頂部本身,但不包括 ’ . ’ 和 '… '),產生一個三元組目錄路徑,目錄名,文件名

這也就說明了 for 循環中的參數是缺一不可的

讀取代碼行數

上面我們已經實現了遍歷目錄和文件了,接下來我們需要讀取文件了
說到讀取文件相信學習過 Python 的朋友都應該知道,無非就是 open 和 with open,沒學習過的朋友也沒關係,這裡簡單教你幾下

首先我們定義一個函數 def countLines(file_name): ,具體代碼如下:

<code> 

def

countLines

(file_name)

:

count =

0

for

file_line

in

open(file_name,

'r'

,encoding=

'utf-8'

).readlines():

if

file_line !=

''

and

file_line !=

'\n'

: count +=

1

print(file_name +

'----'

, count)

return

count/<code>

注意: open 那裡一定要加上編碼格式(encoding=‘utf-8’),否則會報以下錯誤 UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0x84 in position 48: illegal multibyte sequence

你以為這樣就可以了?no,繼續上代碼:

<code>

if

__name__ ==

'__main__'

: startTime = time.perf_counter() getDir_or_File(base_dir) totallines = 0

for

filelist

in

file_lists: totallines = totallines + countLines(filelist)

print

(

'total lines:'

,totallines)

print

(

'Success! Cost Time: %0.2f seconds'

% (time.perf_counter() - startTime))/<code>

代碼測試

到這裡我們的代碼已經編寫完成,我們測試一下我們的程序,測試之前我們先準備幾個 py 文件

來測試下 2019 你一共寫了多少行代碼?

來測試下 2019 你一共寫了多少行代碼?

我們在 demo 文件夾下創建了一個 code.py 文件和一個 test 目錄,而我們的 test 目錄下也有一個 test.py 文件,兩個文件的內容是一樣的,只是一個沒有空行,一個有空行,我們來運行一下我們編寫的程序,我們將路徑指向 demo 目錄

<code>

base_dir

=

'./demo'

/<code>
來測試下 2019 你一共寫了多少行代碼?

OK,運行一下程序

來測試下 2019 你一共寫了多少行代碼?

從圖中我們可以看到程序執行成功了,而且行數也統計出來了,那麼統計到底對不對呢?是正確的,我們上面的 code.py 是有空行的,去掉空行就是 13 行,而 test.py 本來就是 13 行且沒有空行

全部代碼

全部代碼如下:

<code>討論學習群:

887934385

分享python資料

import

os

import

time base_dir =

'需要指定的路徑'

file_lists = [] file_type = [

'py'

]

def

getDir_or_File

(base_dir)

:

global

file_lists

for

parent,dirnames,filenames

in

os.walk(base_dir):

for

filename

in

filenames: file= filename.split(

'.'

)[

-1

]

if

file

in

file_type: file_lists.append(os.path.join(parent,filename))

def

countLines

(file_name)

:

count =

0

for

file_line

in

open(file_name,

'r'

,encoding=

'utf-8'

).readlines():

if

file_line !=

''

and

file_line !=

'\n'

: count +=

1

print(file_name +

'----'

, count)

return

count

if

__name__ ==

'__main__'

: startTime = time.perf_counter() getDir_or_File(base_dir) totallines =

0

for

filelist

in

file_lists: totallines = totallines + countLines(filelist) print(

'total lines:'

,totallines) print(

'Success! Cost Time: %0.2f seconds'

% (time.perf_counter() - startTime))/<code>

打包成可執行程序

其實我們還可以修改一下代碼將代碼打包成 exe 文件,這樣就可以轉發給別人使用了,如我們將這個文件命名為 test.py,使用 pyinstaller 打包程序

<code>

pyinstaller

-F

test

.py

-w

/<code>

這個實現很簡單,但是也有個缺點,就是需要把程序放到你要統計的路徑下才能統計不能指定路徑統計,其實也差不多,只要把程序放到你要統計的目錄就行了,來測試一下:
打包後的程序如下

來測試下 2019 你一共寫了多少行代碼?

放到我的一個 Django 項目下,雙擊 test.exe

來測試下 2019 你一共寫了多少行代碼?

雙擊運行後會在該目錄下創建一個 totalcount 的 txt 文本

來測試下 2019 你一共寫了多少行代碼?

我們打開這個文本看下,可以看到文本中顯示還讀取到了 html 了,是自己設置的哈,並不是代碼寫錯了

來測試下 2019 你一共寫了多少行代碼?

一共讀取了 19 個文件
376 行代碼
用時 0.02s

關於很多朋友問我打包成 exe 運行無法生成 txt 文件,其實還稍作了修改的
我把打包好的 exe 放到了Github了 文件下載地址,想要的朋友可以去下載,喜歡的朋友記得給個star,非常感謝


更多的精彩技術文章可關注公眾號python社區營,提供源碼、視頻教程


分享到:


相關文章: