【问题标题】:Conditional compilation in PythonPython中的条件编译
【发布时间】:2010-10-08 06:50:12
【问题描述】:

如何在 Python 中进行条件编译?

是否使用 DEF ?

【问题讨论】:

  • 请提供一个示例,说明“条件编译”的含义以及如何在实际的 Python 程序中实际使用它。

标签: python conditional-compilation


【解决方案1】:

Python 的编译方式与 C 或 C++ 甚至 Java 不同,python 文件是“即时”编译的,您可以将其视为类似于 Basic 或 Perl 等解释型语言。 1

只需使用 if 语句,您就可以执行与条件编译等效的操作。例如:

if FLAG:
    def f():
        print "Flag is set"
else:
    def f():
        print "Flag is not set"

您可以对创建类、变量设置以及几乎所有内容执行相同操作。

最接近模仿 IFDEF 的方法是使用 hasattr 函数。例如:

if hasattr(aModule, 'FLAG'):
    # do stuff if FLAG is defined in the current module.

您也可以使用 try/except 子句来捕获名称错误,但惯用的方法是在脚本顶部将变量设置为 None。

  1. Python 代码被字节编译成类似 Java 的中间形式,但是通常没有单独的编译步骤。以 .py 结尾的“原始”源文件是可执行的。

【讨论】:

  • 有没有类似 ifdef 的东西?
  • 实用上正确,但技术上错误。 Python 的编译方式与 Java 相同,但编译步骤并未明确向程序员说明。
  • @Arafangion:直截了当......你为什么不在答案中扩展这个 [tiny] 一点点?
  • @rejinacm:ifdef 无论如何都是 C 中的一个古老成语。 python为什么要有它?这没有意义。
  • 这完全不一样。当你编译出一个条件时,绝对不可能在释放时执行条件代码。您在这里拥有的是一些基于某些条件而存在的休眠代码,这些条件可以通过修改环境来激活。这对于任何形式的生产代码都可能是不可取的。也就是说,c 预处理器实际上只是一个文本处理器,可以处理多种语言。你可以用python试试。它适用于 CSS 和 JavaScript。
【解决方案2】:

其实是有办法获取条件编译的,但是非常有限。

if __debug__:
    doSomething()

__debug__ 标志是一种特殊情况。当使用-O-OO 选项调用python 时,__debug__ 将为 false,编译器将忽略该语句。这主要与断言一起使用,这就是如果您“真正编译”脚本并进行优化,断言就会消失的原因。

因此,如果您的目标是添加调试代码,但要防止它减慢或以其他方式影响“发布”构建,那么这就是您想要的。但是你不能为__debug__ 赋值,所以你可以使用它。

【讨论】:

    【解决方案3】:

    使用pypreprocessor

    也可以在 PYPI (Python Package Index) 上找到,并且可以使用 pip 获取。

    基本用法示例为:

    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.output = 'output_file_name.py'
    

    pypreprocessor 导入和调用 parse() 之间的任何地方。

    该模块本质上是C预处理器条件编译的python实现。

    旁注:这与 python2x 和 python 3k 兼容

    免责声明:我是 pypreprocessor 的作者

    更新:

    我之前忘了提。与其他答案中描述的if/elseif _debug: 方法不同,这是一个真正的预处理器。生成的字节码不会包含有条件排除的代码。

    【讨论】:

      【解决方案4】:

      当你导入一个模块时,Python 会自动编译它,所以避免编译它的唯一方法就是不导入它。你可以这样写:

      if some_condition:
        import some_module
      

      但这仅适用于完整的模块。在 C 和 C++ 中,您通常使用预处理器进行条件编译。没有什么可以阻止您在 Python 代码上使用预处理器,因此您可以编写如下内容:

      #ifdef SOME_CONDITION
      def some_function():
        pass
      #endif
      

      通过 C 预处理器运行它,您将获得真正的条件编译,并且只有在定义了 SOME_CONDITION 时才会定义 some_function

      但是(这很重要):条件编译可能不是您想要的。请记住,当您导入模块时,Python 只是执行其中的代码。模块中的 def 和 class 语句实际上是在导入模块时执行的。因此,实现其他语言将使用条件编译的典型方式只是一个普通的 if 语句,例如:

      if some_condition:
        def some_function():
          pass
      

      这只会在some_condition 为真时定义some_function

      正是这样的东西让动态语言如此强大,同时在概念上保持简单。

      【讨论】:

        【解决方案5】:

        在动态环境中没有多大意义。如果你正在寻找函数的条件定义,你可以使用if

        if happy:
            def makemehappy():
                return "I'm good"
        

        【讨论】:

        • 问题是如果不定义happy就不行了。
        【解决方案6】:

        您可以使用这里讨论的方法:Determine if variable is defined in Python 代替 #ifdef

        【讨论】:

          猜你喜欢
          • 2018-03-14
          • 2023-03-04
          • 2012-10-08
          • 2012-06-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多