Heim  >  Artikel  >  Backend-Entwicklung  >  So implementieren Sie ein Codestatistiktool in Python

So implementieren Sie ein Codestatistiktool in Python

php中世界最好的语言
php中世界最好的语言Original
2018-04-09 16:02:471478Durchsuche

Dieses Mal zeige ich Ihnen, wie Sie das Code-Statistik-Tool in Python implementieren. Was sind die Vorsichtsmaßnahmen für die Implementierung des Code-Statistik-Tools in Python?

Frage

Entwerfen Sie ein Programm, um die Anzahl der Codezeilen in einem Projekt zu zählen, einschließlich der Anzahl der Dateien, Codezeilen, und Kommentare Anzahl der Zeilen, Anzahl der Leerzeilen. Versuchen Sie, beim Design flexibler zu sein, indem Sie verschiedene Parameter eingeben, um Projekte in verschiedenen Sprachen zu zählen, zum Beispiel:

# type用于指定文件类型
python counter.py --type python

Ausgabe:

Dateien:10
Codezeilen: 200
Kommentare:100
Leerzeichen:20

Analyse

Dieser sieht einfach aus, ist aber etwas kompliziert Solange wir die Anzahl der Codezeilen in einer Datei korrekt zählen können, ist das Zählen eines Verzeichnisses kein Problem Die kommentierten Codezeilen lauten beispielsweise wie folgt:

1 Einzeilige Kommentare beginnend mit dem Nummernzeichen

# Einzeilige Kommentare

2. Zeilenkommentare in derselben Zeile

"""Dies ist ein mehrzeiliger Kommentar"""
'''Dies ist auch ein mehrzeiliger Kommentar'''
3 Kommentarzeichen

""
Diese 3 Zeilen sind alle das Kommentarzeichen
"""

Unsere Idee ist, zeilenweise Kommentare zu analysieren zusätzlicher Bezeichner in_multi_comment, um zu identifizieren, ob die aktuelle Zeile ein mehrzeiliges Kommentarzeichen ist. Der Standardwert ist „False“, wird auf „True“ gesetzt, wenn ein mehrzeiliger Kommentar beginnt, und auf „False“ gesetzt, wenn das nächste mehrzeilige Kommentarzeichen auftritt. Der Code zwischen dem Startsymbol eines mehrzeiligen Kommentars und dem nächsten Schlusssymbol sollte zur kommentierten Zeile gehören.

Wissenspunkte

Wie man eine Datei richtig liest, und die gelesene Datei sollte eine Zeichenfolge sein Gemeinsame Methoden zur Zeichenfolgenverarbeitung

Vereinfachte Version

Wir werden Schritt für Schritt iterieren und zunächst eine vereinfachte Version des Programms implementieren. und nur Python zählen Eine einzelne Codedatei, unabhängig von mehrzeiligen Kommentaren, ist eine Funktion, die jeder, der neu in Python ist, erreichen kann. Der entscheidende Punkt ist, dass Sie nach dem Lesen jeder Zeile zunächst die Methode „strip()“ verwenden, um die Leerzeichen und Wagenrückläufe auf beiden Seiten der Zeichenfolge zu entfernen

# -*- coding: utf-8 -*-
"""
只能统计单行注释的py文件
"""
def parse(path):
 comments = 0
 blanks = 0
 codes = 0
 with open(path, encoding='utf-8') as f:
 for line in f.readlines():
  line = line.strip()
  if line == "":
  blanks += 1
  elif line.startswith("#"):
  comments += 1
  else:
  codes += 1
 return {"comments": comments, "blanks": blanks, "codes": codes}
if name == 'main':
 print(parse("xxx.py"))

Mehrzeilige Kommentarversion

Wenn Sie nur den Code einzeiliger Kommentare zählen können, ist dies von geringer Bedeutung. Nur die Statistik mehrzeiliger Kommentare kann als echter Code-Statistiker angesehen werden.

# -*- coding: utf-8 -*-
"""

Es kann zählen, wie viele Codezeilen die py-Datei mit Zeilenkommentaren enthält.

"""
def parse(path):
 in_multi_comment = False # 多行注释符标识符号
 comments = 0
 blanks = 0
 codes = 0
 with open(path, encoding="utf-8") as f:
 for line in f.readlines():
  line = line.strip()
  # 多行注释中的空行当做注释处理
  if line == "" and not in_multi_comment:
  blanks += 1
  # 注释有4种
  # 1. # 井号开头的单行注释
  # 2. 多行注释符在同一行的情况
  # 3. 多行注释符之间的行
  elif line.startswith("#") or \
    (line.startswith('"""') and line.endswith('"""') and len(line)) > 3 or \
   (line.startswith("'''") and line.endswith("'''") and len(line) > 3) or \
   (in_multi_comment and not (line.startswith('"""') or line.startswith("'''"))):
  comments += 1
  # 4. 多行注释符的开始行和结束行
  elif line.startswith('"""') or line.startswith("'''"):
  in_multi_comment = not in_multi_comment
  comments += 1
  else:
  codes += 1
 return {"comments": comments, "blanks": blanks, "codes": codes}
if name == 'main':
 print(parse("xxx.py"))

Im vierten Fall oben wird bei mehrzeiligen Kommentarsymbolen die Kennung in_multi_comment invertiert Wenn „““ zum ersten Mal angetroffen wird, ist es „True“. Wenn „““ zum zweiten Mal angetroffen wird, ist es das Endzeichen der Mehrzeile Wenn es negiert wird, ist es falsch. Und so weiter. Beim dritten Mal ist es der Anfang, und wenn es negiert wird, ist es wieder wahr.

Wie kann man also beurteilen, ob andere Sprachen eine Analysefunktion neu schreiben müssen? Wenn Sie genau hinschauen, können die vier Situationen mehrzeiliger Kommentare vier Beurteilungsbedingungen abstrahieren, da die meisten Sprachen einzeilige Kommentare und mehrzeilige Kommentare haben, ihre Symbole jedoch unterschiedlich sind.

CONF = {"py": {"start_comment": ['"""', "'''"], "end_comment": ['"""', "'''"], "single": "#"},
 "java": {"start_comment": ["/*"], "end_comment": ["*/"], "single": "//"}}
start_comment = CONF.get(exstansion).get("start_comment")
end_comment = CONF.get(exstansion).get("end_comment")
cond2 = False
cond3 = False
cond4 = False
for index, item in enumerate(start_comment):
 cond2 = line.startswith(item) and line.endswith(end_comment[index]) and len(line) > len(item)
 if cond2:
 break
for item in end_comment:
 if line.startswith(item):
 cond3 = True
 break
for item in start_comment+end_comment:
 if line.startswith(item):
 cond4 = True
 break
if line == "" and not in_multi_comment:
 blanks += 1
# 注释有4种
# 1. # 井号开头的单行注释
# 2. 多行注释符在同一行的情况
# 3. 多行注释符之间的行
elif line.startswith(CONF.get(exstansion).get("single")) or cond2 or \
 (in_multi_comment and not cond3):
 comments += 1
# 4. 多行注释符分布在多行时,开始行和结束行
elif cond4:
 in_multi_comment = not in_multi_comment
 comments += 1
else:
 codes += 1

Es ist nur eine Konfigurationskonstante erforderlich, um die Symbole einzeiliger und mehrzeiliger Kommentare in allen Sprachen entsprechend cond1 bis cond4 zu markieren. Die verbleibende Aufgabe besteht darin, mehrere Dateien zu analysieren, was mit der Methode os.walk erfolgen kann.

def counter(path):
 """
 可以统计目录或者某个文件
 :param path:
 :return:
 """
 if os.path.isdir(path):
 comments, blanks, codes = 0, 0, 0
 list_dirs = os.walk(path)
 for root, dirs, files in list_dirs:
  for f in files:
  file_path = os.path.join(root, f)
  stats = parse(file_path)
  comments += stats.get("comments")
  blanks += stats.get("blanks")
  codes += stats.get("codes")
 return {"comments": comments, "blanks": blanks, "codes": codes}
 else:
 return parse(path)

Natürlich gibt es noch viel zu tun, um dieses Programm zu perfektionieren, einschließlich der Befehlszeilenanalyse und der Analyse nur einer bestimmten Sprache basierend auf angegebenen Parametern.

Ergänzung:

Python-Implementierung des Codezeilen-Zähltools

Das wollen wir oft count Die Anzahl der Codezeilen des Projekts. Wenn Sie jedoch eine vollständigere Statistikfunktion wünschen, ist dies möglicherweise nicht so einfach. Heute werfen wir einen Blick darauf, wie Sie mit Python ein Codezeilen-Statistiktool implementieren.

Idee:

Besorgen Sie sich zuerst alle Dateien, zählen Sie dann die Anzahl der Codezeilen in jeder Datei und addieren Sie schließlich die Anzahl der Zeilen.

Funktion implementiert:

统计每个文件的行数;
统计总行数;
统计运行时间;
支持指定统计文件类型,排除不想统计的文件类型;
递归统计文件夹下包括子文件件下的文件的行数;

排除空行;

# coding=utf-8
import os
import time
basedir = '/root/script'
filelists = []
# 指定想要统计的文件类型
whitelist = ['php', 'py']
#遍历文件, 递归遍历文件夹中的所有
def getFile(basedir):
 global filelists
 for parent,dirnames,filenames in os.walk(basedir):
  #for dirname in dirnames:
  # getFile(os.path.join(parent,dirname)) #递归
  for filename in filenames:
   ext = filename.split('.')[-1]
   #只统计指定的文件类型,略过一些log和cache文件
   if ext in whitelist:
    filelists.append(os.path.join(parent,filename))
#统计一个文件的行数
def countLine(fname):
 count = 0
 for file_line in open(fname).xreadlines():
  if file_line != '' and file_line != '\n': #过滤掉空行
   count += 1
 print fname + '----' , count
 return count
if name == 'main' :
 startTime = time.clock()
 getFile(basedir)
 totalline = 0
 for filelist in filelists:
  totalline = totalline + countLine(filelist)
 print 'total lines:',totalline
 print 'Done! Cost Time: %0.2f second' % (time.clock() - startTime)

结果:

[root@pythontab script]# python countCodeLine.py
/root/script/test/gametest.php---- 16
/root/script/smtp.php---- 284
/root/script/gametest.php---- 16
/root/script/countCodeLine.py---- 33
/root/script/sendmail.php---- 17
/root/script/test/gametest.php---- 16
total lines: 382
Done! Cost Time: 0.00 second
[root@pythontab script]#

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

怎么对numpy里数组元素赋统一的值

numpy数组与矩阵的乘法怎么使用

Das obige ist der detaillierte Inhalt vonSo implementieren Sie ein Codestatistiktool in Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn