从python源代码中删除真正是注释的字符串文字?

时间:2014-05-16 17:24:46

标签: python parsing

我需要以任何语言快速编写(或借用)自动过滤大量python源代码以删除注释的内容。目标是使目标平台上的代码更紧凑(并且作为旁边的逆向工程甚至更加困难)。我必须积极地修改代码的行为,并且可以使用一些剩余的注释。我的输入和输出应该是.py文本文件,假设是有效的python 2.x(假设:限制为ASCII,我将负责UTF8)。

严格地说,我需要删除

定义的那种评论
  

注释以不属于a的哈希字符(#)开头   字符串文字,并在物理行的末尾结束。

因为python tokenizer已经为我做了,最后代码被分发为.pyc。太糟糕了,因为我清楚地看到如何干净地执行 (唯一有点棘手的部分是python中错综复杂的syntax of string literal。)

我的问题是,粗略地看一下我必须过滤的python源代码,它显示它包含#引入的的大量注释,但只是字符串文字,没有任何有用的任务。这些被明确地保存在.pyc标记化文件中。他们到处都是,我被告知要方便自动生成文档和编辑。许多真正是注释的字符串文字都嵌入在函数定义中,例如:

def OnForceStatusChoice(self,event):
    """Action when a status is selected"""
    self.ExecutionPanel.SetFocus()

另一方面,有大量的字符串文字是有用的文本,包括要显示给用户的英文文本,以及表的初始化。这使得无法自动安全地识别那些真正来自字符串文字的的注释的字符串文字。

从我的抽样中,大多数真正是评论的字符串文字似乎都是由"""引入的(我可能还有很少的例外情况),但我理解足够的python知道我不能安全地删除所有这些字符串文字。

我可以安全地(或对编码风格做出一些陈述和合理的假设)假设

  1. 如果.py文件中的第一件事,忽略#条评论,是一个字符串文字,它可以递归删除吗?如果是,可以通过忽略(并保留)#评论旁边的其他内容来使这条规则变得更强大吗?
  2. 可以删除从任何一行最左边一列开始的任何字符串文字吗?
  3. 可以删除在语法匹配函数定义(如上面的def)之后开始的任何字符串文字吗?如果是,我如何精确定义语法匹配函数定义
  4. 请回答我无法从一个随机的字节集中告诉python,这与现实并不遥远。

1 个答案:

答案 0 :(得分:5)

您所谓的评论实际上是docstrings

  

作为函数体中第一个语句出现的字符串文字被转换为函数的__doc__属性,因此转换为函数的文档字符串。

来自glossary

  

字符串文字,它作为类,函数或模块中的第一个表达式出现。在执行套件时忽略它,它会被编译器识别并放入封闭类,函数或模块的__doc__属性中。由于它可以通过内省获得,因此它是文档对象的规范场所。

使用.pyo命令行开关将项目编译为-OO个文件:

  

-O
  打开基本优化。这会更改文件名   已编译(字节码)文件的扩展名从.pyc.pyo。看到   还PYTHONOPTIMIZE

     

-OO
   放弃文档字符串以及-O优化。

您可以使用compileall module作为命令行实用程序编译项目中的所有文件:

python -OO -m compileall path/to/project/

然而,Python字节码是琐碎的来反编译。删除文档字符串不会对你有太大帮助。

如果你需要更专业的东西,你必须学习如何使用ast module将Python代码解析成解析树,操纵那个树(例如删除所有文档字符串),然后写出转换Python代码。有关该方向的一些指示,请参阅Parse a .py file, read the AST, modify it, then write back the modified source code