你会如何在Python中执行等效的预处理程序指令?

int*_*ion 61 python preprocessor directive equivalent

有没有办法在Python中执行以下预处理程序指令?

#if DEBUG

< do some code >

#else

< do some other code >

#endif
Run Code Online (Sandbox Code Playgroud)

hab*_*bit 104

还有__debug__,这是编译器做预处理的特殊值.

if __debug__:
  print "If this prints, you're not running python -O."
else:
  print "If this prints, you are running python -O!"
Run Code Online (Sandbox Code Playgroud)

__debug__将由编译器替换为常量0或1,优化器将if 0:在解释源之前删除任何行.

  • 解决方案的问题是默认情况下__debug__为true,如果使用-O命令行开关运行python,则只有false.我发现通常不使用此开关,这不一定是用户期望的. (11认同)
  • @Moe:看起来旗帜的逻辑似乎是倒退的.如果__debug__的计算结果为True,我希望我*在调试模式下运行,情况并非如此. (6认同)
  • 但它允许您在开发中进行断言,如果您只在生产服务器上使用“-O”,这些断言就会被删除。:-) 在阅读本文之前我认为这是不可能的! (4认同)
  • 这也让我了解到“assert”使用“__debug__”,这使得开发断言更加具体:https://docs.python.org/2/reference/simple_stmts.html#assert (2认同)
  • -O 代表像其他语言一样优化,这里没有任何落后。 (2认同)

Eva*_*ice 34

我编写了一个名为pypreprocessor的python预处理程序,它完全按照您所描述的内容执行.

源代码和文档可在Google Code上找到.

也可以通过PYPI下载/安装该软件包.

这是一个完成你所描述的例子.

from pypreprocessor import pypreprocessor

pypreprocessor.parse()

#define debug

#ifdef debug
print('The source is in debug mode')
#else
print('The source is not in debug mode')
#endif
Run Code Online (Sandbox Code Playgroud)

pypreprocessor不仅可以进行动态预处理.要查看更多用例示例,请查看Google Code上的项目.

更新:有关pypreprocessor的更多信息

我完成预处理的方式很简单.从上面的示例中,预处理器导入在pypreprocessor模块中创建的pypreprocessor对象.当你在预处理器上调用parse()时,它自己使用它导入的文件并生成一个自己的临时副本,它会注释掉所有预处理器代码(以避免预处理器在无限循环中递归调用自身)和评论所有未使用的部分.

如果模块抛出异常或崩溃,则注释掉这些行与删除它们相反,必须保留错误回溯上的行号.而且我甚至已经将错误回溯重写为报告反映了崩溃的模块的正确文件名.

然后,包含后处理代码的生成文件即时执行.

使用这种方法而不仅仅是在代码中内联添加一堆if语句的好处是,没有浪费执行时间来评估无用语句,因为代码的注释部分将从编译的.pyc文件中排除.

缺点(以及我创建模块的最初原因)是你不能在同一个文件中同时运行python 2x和python 3x,因为pythons interpreter在执行代码之前会运行完整的语法检查,并且会拒绝任何特定于版本的代码.允许预处理器运行:: sigh ::.我最初的目标是能够在同一个文件中并行开发2x和3x代码,根据运行的内容创建特定于版本的字节码.

无论哪种方式,预处理器模块对于实现常见的c风格预处理功能仍然非常有用.同样,预处理器能够将后处理代码输出到文件中以供以后使用.

此外,如果要生成包含所有预处理程序指令的版本以及排除的任何#ifdef,则只需在调用parse()之前在预处理程序代码中设置标志即可.这使得从特定于版本的源文件中删除不需要的代码是一个步骤(对于爬行代码并手动删除if语句).

  • 遗憾的是,这个软件包似乎不再受支持,目前甚至无法通过“pip install”进行安装(其他人已经在存储库中记录了此问题)。 (2认同)

Cha*_*tin 22

我怀疑你会讨厌这个答案.你在Python中这样做的方式是

# code here
if DEBUG:
   #debugging code goes here
else:
   # other code here.
Run Code Online (Sandbox Code Playgroud)

由于python是一个解释器,因此不需要应用预处理步骤,并且没有特殊优势来使用特殊语法.

  • 作为翻译并没有任何关系.没有人声称Java被解释,但Java使用完全相同的技术(D语言是另一个例子).Python实际上是一个编译器,它将源代码编译为字节码并在VM中执行,就像Java一样. (12认同)
  • 格雷格,回去想想那个答案。(1) Java 与 Python 不同,有一个*单独的*编译阶段。(2) 虽然它们从未流行起来,但已经出现了几个 java 预处理器。... (2认同)
  • @Charlie(续)我最初编写 pypreprocessor 用作更新 python (pypi) 库的工具,使其能够在 py3k 和 python2x 中运行。不幸的是,我发现无法单独在 python 中创建 **true** 预处理器的困难方法,因为真正的预处理器实际上在解释器中执行 ** 在 ** 源被词法/解析之前。最好的选择是在 python 中包含一个真正的预处理器,但是,由于 C 中宏替换的猖獗滥用,核心开发人员不会用 10 英尺的极点接触预处理器主题。 (2认同)

Rob*_*uld 10

您可以在Python中使用预处理器.只需通过bin目录中的cpp(C-Preprocessor)运行脚本即可.不过我已经用Lua做到了这一点,简单解释的好处超过了更复杂的编译恕我直言.


phi*_*hag 5

您可以只使用普通的语言结构:

DEBUG = True
if DEBUG:
  # Define a function, a class or do some crazy stuff
  def f():
    return 23
else:
  def f():
    return 42
Run Code Online (Sandbox Code Playgroud)

  • 如果能跨模块使用那就完美了。但是,DEBUG 似乎仅对单个文件可见,您将使用其他机制将其传播到文件之间...... (2认同)