在我以前的编程中C
,代码部分仅用于调试目的(记录命令等)。这些语句可以通过使用#ifdef
预处理器指令完全禁用生产,如下所示:
#ifdef MACRO
controlled text
#endif /* MACRO */
做类似事情的最佳方法是什么python
?
在我以前的编程中C
,代码部分仅用于调试目的(记录命令等)。这些语句可以通过使用#ifdef
预处理器指令完全禁用生产,如下所示:
#ifdef MACRO
controlled text
#endif /* MACRO */
做类似事情的最佳方法是什么python
?
如果您只想禁用日志记录方法,请使用该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
现在检查它们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
如您所见,只有f
“优化”。
重要的是要了解在 Python 中def
和class
是两个常规的可执行语句......
import os
if os.name == "posix":
def foo(x):
return x * x
else:
def foo(x):
return x + 42
...
因此,要使用 C 和 C++ 中的预处理器执行您的操作,您可以使用常规的 Python 语言。
Python 语言在这一点上与 C 和 C++ 根本不同,因为不存在“编译时间”的概念,只有两个阶段是“解析时间”(读入源代码时)和解析代码时的“运行时间” (通常主要由定义语句组成,但这确实是任意 Python 代码)被执行。
我使用术语“解析时间”,即使从技术上讲,在转换中读取源代码时是对字节码的完整编译,因为 C 和 C++ 编译的语义不同,例如函数的定义发生在那个阶段(相反,它发生在 Python 的运行时)。
甚至相当于#include
C 和 C++(在 Python 中是import
)的等价物是在运行时而不是在编译(解析)时执行的常规语句,因此它可以放在常规 pythonif
中。很常见的是,例如,如果系统上不存在特定的可选 Python 库,则import
在一个try
块内部将为某些函数提供替代定义。
最后请注意,在 Python 中,您甚至可以通过使用在运行时从头开始创建新的函数和类exec
,而不必在源代码中包含它们。您也可以直接使用代码组装这些对象,因为类和函数确实只是常规对象(不过,这通常只对类进行)。
有一些工具会尝试将定义和def
语句视为“静态”,例如对 Python 代码进行静态分析以在可疑片段上生成警告或创建不依赖于系统上的特定 Python 安装以运行程序。然而,所有这些都需要能够考虑到 Python 在这方面比 C 或 C++ 更具动态性,并且它们还允许为自动分析失败的地方添加异常。class
import
这是我用来区分 Python Tk 程序的 Python 2 和 3 的示例:
导入系统 如果 sys.version_info[0] == 3: 从 tkinter 导入 * 从 tkinter 导入 ttk 别的: 从 Tkinter 导入 * 导入ttk """ 其余代码 """
希望这是一个有用的说明。
据我所知,你必须使用实际的if
陈述。没有预处理器,因此没有预处理器指令的类似物。
编辑:实际上,看起来这个问题的最佳答案会更有启发性:你将如何在 Python 中执行相当于预处理器指令的操作?
假设有一个特殊变量__debug__
,当与if
语句一起使用时,将被评估一次,然后在执行期间不再评估。
我知道没有直接的等价物,因此您可能想要缩小并重新考虑您过去使用预处理器解决的问题。
如果它只是您所追求的诊断日志记录,那么有一个全面的日志记录模块应该涵盖您想要的所有内容以及更多内容。
http://docs.python.org/library/logging.html
你还用预处理器做什么?测试配置?有一个配置模块。
http://docs.python.org/library/configparser.html
还要别的吗?
如果您#ifdef
用于检查可能已在当前文件上方的范围内定义的变量,则可以使用异常。例如,我有一些脚本,我想在内部ipython
和外部以不同的方式运行ipython
(例如,显示绘图与保存绘图)。所以我添加
ipy = False
try:
ipy = __IPYTHON__
except NameError:
pass
这给我留下了一个变量ipy
,它告诉我是否__IPYTHON__
在当前脚本上方的范围内声明。这是我所知道的#ifdef
Python 中最接近的并行函数。
因为ipython
,这是一个很好的解决方案。您可以在其他上下文中使用类似的构造,其中调用脚本设置变量值并相应地检查内部脚本。当然,这是否有意义取决于您的具体用例。
如果你正在使用 Spyder,你可能只需要这个:
try:
print(x)
except:
#code to run under ifndef
x = "x is defined now!"
#other code
第一次,你运行你的脚本,你会运行下面的代码#code to run under ifndef
,第二次,你会跳过它。希望它有效:)
这可以通过传递命令行参数来实现,如下所示:
import sys
my_macro = 0
if(len(sys.argv) > 1):
for x in sys.argv:
if(x == "MACRO"):
my_macro = 1
if (my_macro == 1):
controlled text
尝试运行以下脚本并在此之后观察结果:
python myscript.py MACRO
希望这可以帮助。