dan*_*ast 33 python preprocessor
C
我以前的编程只有代码部分用于调试目的(记录命令等).通过使用#ifdef
预处理器指令可以完全禁用这些语句,如下所示:
#ifdef MACRO
controlled text
#endif /* MACRO */
Run Code Online (Sandbox Code Playgroud)
做类似事情的最佳方法是什么python
?
nne*_*neo 27
如果您只想禁用日志记录方法,请使用该logging
模块.如果将日志级别设置为排除,例如调试语句,那么logging.debug
将非常接近无操作(它只检查日志级别并返回而不插入日志字符串).
如果你想在字节码编译时根据特定变量实际删除代码块,那么你唯一的选择就是相当神秘的__debug__
全局变量.True
除非将-O
标志传递给Python(或PYTHONOPTIMIZE
在环境中设置为非空),否则此变量设置为.
如果__debug__
在if
语句中使用,则该if
语句实际上仅编译为True
分支.这种特殊的优化与Python所获得的预处理器宏一样接近.
请注意,与宏不同,您的代码在两个分支中仍然必须在语法上正确if
.
为了说明如何__debug__
工作,请考虑以下两个功能:
def f():
if __debug__: return 3
else: return 4
def g():
if True: return 3
else: return 4
Run Code Online (Sandbox Code Playgroud)
现在检查出来dis
:
>>> dis.dis(f)
2 0 LOAD_CONST 1 (3)
3 RETURN_VALUE
>>> dis.dis(g)
2 0 LOAD_GLOBAL 0 (True)
3 JUMP_IF_FALSE 5 (to 11)
6 POP_TOP
7 LOAD_CONST 1 (3)
10 RETURN_VALUE
>> 11 POP_TOP
3 12 LOAD_CONST 2 (4)
15 RETURN_VALUE
16 LOAD_CONST 0 (None)
19 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
如您所见,只有f
"优化".
重要的是要理解在Python中def
并且class
是两个常规的可执行语句......
import os
if os.name == "posix":
def foo(x):
return x * x
else:
def foo(x):
return x + 42
...
Run Code Online (Sandbox Code Playgroud)
因此,要使用C和C++中的预处理器执行操作,可以使用常规Python语言.
Python语言在这一点上与C和C++根本不同,因为没有"编译时"的概念,只有两个阶段是"解析时间"(当读入源代码时)和解析代码时的"运行时" (通常主要由定义语句组成,但实际上是任意Python代码)被执行.
我正在使用术语"解析时间",即使技术上在转换中读取源代码是对字节码的完整编译,因为C和C++编译的语义不同,例如函数的定义在该阶段发生(相反,它发生在Python的运行时).
甚至相当于#include
C和C++(在Python中import
)是一个在运行时而不是在编译(解析)时执行的常规语句,因此它可以放在常规python中if
.相当常见的是例如具有import
一个内部try
块,将某些功能提供替代定义,如果一个特定的可选Python库中不存在在系统上.
最后请注意,在Python中,您甚至可以在运行时通过使用创建新的函数和类exec
,而不必在源代码中使用它们.您也可以使用代码直接组装这些对象,因为类和函数确实只是常规对象(但这通常仅针对类进行).
有一些工具,而是尽量考虑def
和class
定义,并import
声明为"静态",例如做的Python代码静态分析,生成可疑碎片警告或创建不依赖于具有独立的可部署的包系统上运行程序的特定Python安装.然而,所有这些都需要能够考虑到Python在这个领域比C或C++更具动态性,并且它们还允许在自动分析失败的地方添加异常.
小智 7
这是一个示例,用于区分我的Python Tk程序的Python 2和3:
导入系统 如果sys.version_info [0] == 3: 从tkinter导入* 从tkinter导入ttk 其他: 从Tkinter进口* 导入ttk “”“其余代码”“”
希望这是一个有用的例证。
据我所知,你必须使用实际的if
陈述.没有预处理器,因此没有预处理器指令的模拟.
编辑:实际上,看起来这个问题的最佳答案将更具启发性:你将如何在Python中执行等效的预处理程序指令?
据推测,有一个特殊变量__debug__
,当与if
语句一起使用时,将被评估一次,然后在执行期间不再评估.