有没有办法在 Python 中执行以下预处理器指令?
#if DEBUG
< do some code >
#else
< do some other code >
#endif
有没有办法在 Python 中执行以下预处理器指令?
#if DEBUG
< do some code >
#else
< do some other code >
#endif
有__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:
在解释您的源代码之前删除任何行。
我编写了一个名为 pypreprocessor 的 python 预处理器,它完全符合您的描述。
这是一个完成您所描述的示例。
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 解释器在执行代码之前会运行完整的语法检查,并且会拒绝之前的任何版本特定代码允许预处理器运行::sigh::。我最初的目标是能够在同一个文件中并排开发 2x 和 3x 代码,这将根据运行的内容创建特定于版本的字节码。
无论哪种方式,预处理器模块对于实现常见的 c 样式预处理功能仍然非常有用。此外,如果您愿意,预处理器能够将后处理的代码输出到文件以供以后使用。
此外,如果您想生成一个包含所有预处理器指令以及任何被排除的#ifdef 的版本,它就像在调用 parse() 之前在预处理器代码中设置一个标志一样简单。这使得从特定于版本的源文件中删除不需要的代码成为一步过程(而不是爬取代码并手动删除 if 语句)。
我怀疑你会讨厌这个答案。你在 Python 中这样做的方式是
# code here
if DEBUG:
#debugging code goes here
else:
# other code here.
由于 python 是一个解释器,因此不需要应用预处理步骤,并且具有特殊语法也没有特别的优势。
您可以在 Python 中使用预处理器。只需通过 bin 目录中的 cpp(C 预处理器)运行脚本。然而,我已经用 Lua 做到了这一点,并且易于解释的好处超过了更复杂的编译恕我直言。
您可以只使用正常的语言结构:
DEBUG = True
if DEBUG:
# Define a function, a class or do some crazy stuff
def f():
return 23
else:
def f():
return 42
另一种方法是使用 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
改用普通的 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 - 一个通用的预处理器。