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

fgr*_*ieu -3 python parsing

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

严格地说,我也不会需要删除通过定义的那种评论

注释以散列字符(#)开头,该散列字符不是字符串文字的一部分,并在物理行的末尾结束.

因为python tokenizer已经为我做了,最后代码被分发为.pyc.太糟糕了,因为我清楚地看到如何做的是干净的(唯一稍微棘手的部分是令人费解的字符串常量的语法在Python).

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

def OnForceStatusChoice(self,event):
    """Action when a status is selected"""
    self.ExecutionPanel.SetFocus()
Run Code Online (Sandbox Code Playgroud)

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

从我的抽样中,大多数真正是注释的字符串文字似乎都是由"""(很少有例外,我也许可以忍受),但我理解足够的python知道我无法安全地删除所有这些字符串文字.

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

  1. 如果.py文件中的第一件事,忽略#注释,是一个字符串文字,它可以递归删除?如果是的话,通过忽略(并保留)#评论旁边的其他内容,可以使这条规则变得更强大吗?
  2. 可以删除从任何行的最左列开始的任何字符串文字?
  3. def可以删除在语法匹配函数定义(如上所述)之后开始的任何字符串文字?如果是,我如何精确定义 语法匹配函数定义

请回答我无法从随机的字节集合中告诉python,这与现实相差无几.

Mar*_*ers 5

你所谓的评论是docstrings:

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

并从词汇表:

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

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

-O
打开基本优化.这会将已编译(字节码)文件的文件扩展名更改.pyc.pyo.另见PYTHONOPTIMIZE.

-OO
除了-O优化之外,还要放弃文档字符串.

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

python -OO -m compileall path/to/project/
Run Code Online (Sandbox Code Playgroud)

但是,Python字节码对于反编译来说是微不足道的.删除文档字符串不会对你有多大帮助.

如果你还需要更专业的东西,你必须学习如何使用ast模块将Python代码解析成解析树,操作那个树(例如删除所有文档字符串),然后写出转换后的Python代码.请参阅解析.py文件,读取AST,修改它,然后在该方向上写回一些指针的修改后的源代码.

  • @fgrieu:`.pyo` 文件实际上只是 `.pyc` 文件,但使用新的扩展名来反映它们不再包含 assert 语句并且将 `__debug__` 设置为 `False`;如果您愿意,可以重命名它们。 (2认同)
  • @fgrieu:你的*测试套件*应该可以防止灾难.断言对开发人员来说很好,但测试套件更好. (2认同)
  • @fgrieu:`if some_constraint_not_met:引发AssertionError('错误信息')`.使用它代替`assert`语句,它永远不会被剥离. (2认同)