一、注释
在运行程序时,注释不会被执行,它只是对程序代码进行解释说明,让别人可以看懂程序代码的作用,能够大大增强程序的可读性。
要想通过代码实现一键提取Python文件或SQL文件中的注释,首先要清楚这两种文件中注释的格式。
1. 单行注释
Python文件:以"# "开头,后边接着写注释文字;("#"后面一般跟一个空格)
SQL文件:(1)以"# "开头,后边接着写注释文字;
(2)以"-- "开头,后边接着写注释文字;
2. 多行注释
Python文件:用一组三引号 """......"""包裹,里面写多行注释内容;
SQL文件:用 /*......*/包裹,里面写多行注释内容。
二、思路
正则表达式 + 文件备份操作
1. 正则表达式:正则表达式(regular expression)描述了一种字符串匹配的模式,可以用于匹配或查找符合某些规则的字符串;
2. 文件备份操作:Python中的文件读写操作,实现对源码的备份。
三、代码实现
写在前面:
如果不用代码实现,手动一行行的去删文件中的代码行,保留注释部分也是可以实现的,但是对于那种动不动就数百行代码的文件,这种方法显然效率比较低了。
提取出来的注释文件有什么用呢?个人认为,一个程序文件的注释,相当于这个程序实现功能的思路,根据注释去写代码,其实就是培养自己解决功能实现问题的思路,也就是我们常说的"算法"。
下面代码以Python文件为例:
1. 导包及定义函数
# 导包:使用正则表达式要用到re模块
import re
# 定义函数,用于获取Python文件的单行注释,find single_line comments
def findsl_comments(code):
# 用正则表达式定义字符串匹配的模式pattern,或者说规则
pattern = '# (.*)'
comments = re.findall(pattern, code)
return comments
# 定义函数,用于获取Python文件的多行注释,find multiline comments
def findml_comments(code):
pattern = re.compile('(?:""")(.*?)(?:""")', re.DOTALL)
comments = pattern.findall(code)
return comments
其中:
re.findall() 方法用于返回字符串中所有不重叠的匹配项的列表。如果模式中存在一个或多个匹配组,会返回一个组列表;如果模式有多个组,则会返回一个元组列表,即列表嵌套元组。
re.compile() 方法用于编译一个正则表达式模式,返回一个pattern(模式)对象。
2. 创建注释文件
# 用户录入当前目录下任意Python文件名, 完成对注释文件的创建.
# 1. 提示用户录入要备份的源代码文件名, 并接收.
src_filePath = input("请录入要提取注释的Python文件名: ")
# 2. 判断上述的文件名是否合法, 如果合法, 就生成注释文件名:文件名[注释].后缀名
# 2.1 获取最后1个.的索引.
index = src_filePath.rfind(".")
# 2.2 判断输入的文件名是否合法.
if index < 1:
exit("文件名输入有误, 程序结束")
else:
# 2.3 文件名合法, 拼接生成注释文件名.
dest_filePath = src_filePath[:index] + "[注释]" + src_filePath[index:]
3. 抽取源文件的注释,同时写入到注释文件中
# 3. 文件读写操作
# “只读”模式打开源文件,“只写”模式打开注释文件
with open(src_filePath, 'r', encoding='utf-8') as src_f, open(dest_filePath, 'w', encoding='utf-8') as dest_f:
# 读出源文件数据,获取要匹配的字符串
data = src_f.read()
# 调用2个函数获取匹配到的字符串
docstring_s = findsl_comments(data)
docstring_m = findml_comments(data)
# 遍历,写入Python多行注释
for i in range(len(docstring_m)):
comments = docstring_m[i]
dest_f.write(f'"""{comments}\n"""\n')
# 遍历,写入Python单行注释
for i in range(len(docstring_s)):
comments = docstring_s[i]
dest_f.write(f"# {comments}\n")
# 4. 输出注释提取完成.
print('当前文件注释提取完成!')
这里,参考常见的注释书写方式,先写入多行注释,在写入单行注释。
四、举一反三:MySQL文件
MySQL文件的注释提取,参考Python文件,制定其对应的注释格式即可,以下代码供参考:
# 定义函数,获取sql文件的单行注释,find mysql single_line comments
def find_mysql_comments_sl(code):
# 用正则表达式定义字符串匹配的模式pattern,或者说规则
pattern = '-- (.*)'
comments = re.findall(pattern, code)
return comments
# 定义函数,获取sql文件多行注释,find mysql multiline comments
def find_mysql_comments_ml(code):
pattern = re.compile('(?:/\*)(.*?)(?:\*/)', re.DOTALL)
comments = pattern.findall(code)
return comments
写入注释文件时,注意格式化输出内容的写法即可:
# 输出mysql多行注释
for i in range(len(doc_mysql)):
comments = doc_mysql[i]
dest_f.write(f"/*{comments}*/\n")
# 输出mysql单行注释
for i in range(len(doc_mysql)):
comments = doc_mysql[i]
dest_f.write(f"-- {comments}\n")
五、 不足之处
经实测,上述代码可以实现分别抽取Python文件的多行注释及单行注释,但存在的不足之处是:
(1)写在多行注释中的单行注释也会被单独提取出来;
(2)单行注释写在代码后面时,提取出来后不会在原位置,而是从行首开始写;
(3)由于多行注释和单行注释是分别抽取的,所以与源文件中注释的的位置会有差异。
以上是需要改进的点,欢迎评论区各位多提优化改进意见。