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

问题描述 投票:54回答:7

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

#if DEBUG

< do some code >

#else

< do some other code >

#endif
python preprocessor equivalent directive
7个回答
99
投票

__debug__,这是编译器预处理的特殊值。

if __debug__:
  print "If this prints, you're not running python -O."
else:
  print "If this prints, you are running python -O!"

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


32
投票

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

The source and documentation is available on GitHub

The package can also be downloaded/installed through the 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

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

更新:有关pypreprocessor的更多信息

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

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

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

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

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

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

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


22
投票

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

# code here
if DEBUG:
   #debugging code goes here
else:
   # other code here.

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


10
投票

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


3
投票

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

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

2
投票

另一种方法是使用bash脚本注释掉仅与调试相关的代码部分。下面是一个示例脚本,用于注释其中包含“#DEBUG”语句的行。它还可以再次删除这些注释标记。

if [ "$1" == "off" ]; then
  sed -e '/^#/! {/#DEBUG/ s/^/#/}' -i *.py
  echo "Debug mode to $1"
elif [ "$1" == "on" ]; then
  sed -e '/#DEBUG/ s/^#//' -i *.py
  echo "Debug mode to $1"
else
  echo "usage: $0 on | off"
fi

0
投票
  • Python如果不能从数组中消除元素。
  • C预编译器不处理#!或者根据需要以#开头的其他行。
  • pypreprocessor似乎是特定于python的

使用常见的m4,如下所示:

ifelse(DEBUG,True,dnl`
  < do some code >
dnl,dnl`
  < do some other code >dnl
')

ifelse(
  M4_CPU,x86_64,`
    < do some code specific for M4_CPU >
',M4_CPU,arm,`
    < do some code specific for M4_CPU >
',M4_CPU,ppc64le,`
    < do some code specific for M4_CPU >
')

ifelse(
  M4_OS,windows,`
    < do some code specific for M4_OS >
  ',M4_OS,linux,`
    < do some code specific for M4_OS >
  ',M4_OS,android,`
    < do some code specific for M4_OS >
')

m4 -D DEBUG =三维MCh_OS = android-D MCh_ChPU = arm test.poch.ch> test.by

© www.soinside.com 2019 - 2024. All rights reserved.