如何在 Python 中执行相当于预处理器指令的操作?

发布于 2024-07-12 22:51:30 字数 138 浏览 8 评论 0原文

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

#if DEBUG

< do some code >

#else

< do some other code >

#endif

Is there a way to do the following preprocessor directives in Python?

#if DEBUG

< do some code >

#else

< do some other code >

#endif

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

蘑菇王子 2024-07-19 22:51:31

我编写了一个名为 pypreprocessor 的 python 预处理器,它完全按照您的描述进行操作。

源代码和文档可在 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

pypreprocessor 的功能远不止即时预处理。 要查看更多用例示例,请查看 Google Code 上的项目。

更新:有关 pypreprocessor 的更多信息

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

如果模块引发异常或崩溃,则注释掉这些行(而不是删除它们)对于在错误回溯中保留行号是必要的。 我什至重写了错误回溯以报告反映崩溃模块的正确文件名。

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

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

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

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

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

I wrote a python preprocessor called pypreprocessor that does exactly what you're describing.

The source and documentation is available on GitHub.

The package can also be downloaded/installed through the PyPI.

Here's an example to accomplish what you're describing.

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 is capable of a lot more than just on-the-fly preprocessing. To see more use case examples check out the project on Google Code.

Update: More info on pypreprocessor

The way I accomplish the preprocessing is simple. From the example above, the preprocessor imports a pypreprocessor object that's created in the pypreprocessor module. When you call parse() on the preprocessor it self-consumes the file that it is imported into and generates a temp copy of itself that comments out all of the preprocessor code (to avoid the preprocessor from calling itself recursively in an infinite loop) and comments out all of the unused portions.

Commenting out the lines is, as opposed to removing them, is necessary to preserve line numbers on error tracebacks if the module throws an exception or crashes. And I've even gone as far as to rewrite the error traceback to report reflect the proper file name of the module that crashed.

Then, the generated file containing the postprocessed code is executed on-the-fly.

The upside to using this method over just adding a bunch of if statements inline in the code is, there will be no execution time wasted evaluating useless statements because the commented out portions of the code will be excluded from the compiled .pyc files.

The downside (and my original reason for creating the module) is that you can't run both python 2x and python 3x in the same file because pythons interpreter runs a full syntax check before executing the code and will reject any version specific code before the preprocessor is allowed to run ::sigh::. My original goal was to be able to develop 2x and 3x code side-by-side in the same file that would create version specific bytecode depending on what it is running on.

Either way, the preprocessor module is still very useful for implementing common c-style preprocessing capabilities. As well as, the preprocessor is capable of outputting the postprocessed code to a file for later use if you want.

Also, if you want to generate a version that has all of the preprocessor directives as well as any of the #ifdefs that are excluded removed it's as simple as setting a flag in the preprocessor code before calling parse(). This makes removing unwanted code from a version specific source file a one step process (vs crawling through the code and removing if statements manually).

帅哥哥的热头脑 2024-07-19 22:51:31

我怀疑你会讨厌这个答案。 在 Python 中执行此操作的方式是:

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

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

I suspect you're gonna hate this answer. The way you do that in Python is

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

Since python is an interpreter, there's no preprocessing step to be applied, and no particular advantage to having a special syntax.

皇甫轩 2024-07-19 22:51:31

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

You can use the preprocessor in Python. Just run your scripts through the cpp (C-Preprocessor) in your bin directory. However I've done this with Lua and the benefits of easy interpretation have outweighed the more complex compilation IMHO.

巡山小妖精 2024-07-19 22:51:31

您可以只使用正常的语言结构:

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

You can just use the normal language constructs:

DEBUG = True
if DEBUG:
  # Define a function, a class or do some crazy stuff
  def f():
    return 23
else:
  def f():
    return 42
失与倦" 2024-07-19 22:51:31

另一种方法是使用 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

An alternative method is to use a bash script to comment out portions of code which are only relevant to debugging. Below is an example script which comments out lines that have a '#DEBUG' statement in it. It can also remove these comment markers again.

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
北方的韩爷 2024-07-19 22:51:31
  • Python if 无法消除数组中的元素。
  • 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=True -D M4_OS=android -D M4_CPU=arm test.py.m4 > 测试.py

  • Python if cannot eliminate elements from arrays.
  • C precompilers do not handle #! or other lines beginning with # as needed.
  • pypreprocessor seems to be python specific

Use a common m4 instead, like this:

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

独夜无伴 2024-07-19 22:51:31

使用 gpp - 通用预处理器。

Use gpp - a general-purpose preprocessor.

热血少△年 2024-07-19 22:51:31

我使用 PIE。 PIE 是在 Python 3 中进行预处理的最佳方法。PIE 允许您在 Python 中进行任何类型的预处理。

这是一个完成您所描述的内容的示例。

#define debug

#ifdef debug
print('The source is in debug mode')
#else
print('The source is not in debug mode')
#endif

I use PIE. PIE is the best way to preprocess in Python 3. PIE allows you to do any sort of preprocessing in Python.

Here's an example to accomplish what you're describing.

#define debug

#ifdef debug
print('The source is in debug mode')
#else
print('The source is not in debug mode')
#endif
旧时模样 2024-07-19 22:51:30

__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: 行。

There's __debug__, which is a special value that the compiler does preprocess.

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

__debug__ will be replaced with a constant 0 or 1 by the compiler, and the optimizer will remove any if 0: lines before your source is interpreted.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文