如何在 Python 中实现与预处理器指令等效的功能?

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

#if DEBUG


< do some code >


#else


< do some other code >


#endif
49847 次浏览

我想你会讨厌这个答案的,你在 Python 中的方式是

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

因为 python 是一个解释器,所以不需要应用预处理步骤,也没有特殊语法的优势。

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

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

您可以在 Python 中使用预处理器。只需在 bin 目录中的 cpp (C-PreProcessing)中运行脚本即可。然而,我已经使用 Lua 完成了这项工作,简单解释的好处超过了更复杂的编译。

有一个 __debug__,它是编译器进行预处理的一个特殊值。

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

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

我写了一个 Python 预处理程序,叫做 pypreProcessing,它完全符合您的描述。

源代码和文档可以在 GitHub 上获得。

还可以通过 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

Pypre 处理器的能力远远不止于动态预处理。要查看更多的用例示例,请查看 GoogleCode 上的项目。

更新: 更多关于 pypreProcessing 的信息

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

如果模块抛出异常或崩溃,则需要注释掉这些行,而不是删除它们,以便在错误回溯中保留行号。我甚至还重写了错误回溯,以反映崩溃的模块的正确文件名。

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

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

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

不管怎样,预处理器模块对于实现常见的 c 风格预处理功能仍然非常有用。此外,如果需要,预处理器还可以将后处理代码输出到文件中供以后使用。

另外,如果您想生成一个版本,其中包含所有的预处理器指令以及任何被排除在外的 # ifdefs,那么只需在调用 parse ()之前在预处理器代码中设置一个标志即可。这使得从版本特定的源文件中删除不需要的代码成为一个步骤过程(相对于爬行遍历代码和手动删除 if 语句)。

另一种方法是使用 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
  • 如果不能从数组中消除元素,则使用 Python。
  • C 预编译器根据需要不处理 # ! 或以 # 开头的其他行。
  • Pypreprocess 似乎是特定于 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 = True-D M4 _ OS = android-D M4 _ CPU = arm test.py.M4 > test.py

使用 Gpp-通用预处理器。