Python项目的调试和发布构建策略

3
我有一款软件(2100 SLOC),我认为它可以运行两个不同版本:一个版本向控制台提供详细的调试信息,另一个版本则是经过优化的发布版本。
我的目标是只维护单一的git分支。有没有一种方法可以标记代码中的调试部分并告知Python解释器忽略这些代码?
可能的应用包括:打印语句、Python的日志记录工具、性能分析和断言 [编辑:通过设置-O标志来忽略它们]。

1
你在哪里看到装饰器是不好的实践?你是否考虑过在两个不同的环境中设置不同的日志输出级别,只使用 logging 而不是 print?当调用Python时,你可以使用 -O 来排除可能存在的任何 assertions - jonrsharpe
@jonrsharpe 我在这里阅读了有关装饰器的内容(https://dev59.com/MnRA5IYBdhLWcg3wsgFP#862899)。我不熟悉解释器如何处理日志记录。 - noumenal
这就是为什么你不会将其用于标记每个函数作为可调试的,不清楚你为什么认为这在这里是相关的。 - jonrsharpe
@jonrsharpe 那是我关于该语句普适性的一个思维错误。我已经更新了问题。 - noumenal
1
我在创建我的第一个大型Python项目时发现这个链接非常有用:http://jeffknupp.com/blog/2013/08/16/open-sourcing-a-python-project-the-right-way/ - jonrsharpe
2个回答

4
我认为你过于复杂化了这个问题。在开发和生产环境中,最好不要有不同的代码路径,只需要有不同的配置即可,否则很难确定你的测试是否真正反映了代码部署后的行为。像分析和调试代码这样的事情应该是外部过程,你应该在代码库上运行那些而不是作为代码库的一部分。
如果你所关心的只是日志记录,可以在不同的环境中设置不同的输出级别。假设你已经有了标准库日志设置,你可以这样做:
import logging
import os

logging.basicConfig(
    level=getattr(logging, os.getenv('LOG_LEVEL', 'DEBUG')),
    ...
)

在你的入口点,你可以设置一个显式的LOG_LEVEL环境变量(其中一个允许的值),用于在生产环境中默认为DEBUG,而在开发环境中则默认为生产级别(例如ERROR)并在开发环境中显式设置。然后你应该通过logging输出消息,不要使用print。同时,你还应该让日志处理程序处理任何字符串插值,即使用:
logger.info('hello %s', 'world')

与其:

logger.info('hello %s' % 'world')  # or logger.info('hello {}'.format('world'))

这样,如果该日志级别未激活,则可以为您优化插值。


我期待着重构我的项目并在我的IDE中设置一个额外的-O运行参数。我唯一剩下的担忧是,在-O模式下是否会调用isEnabledFor - noumenal
1
@noumenal,除非你只是为了记录而执行计算密集型操作(在这种情况下,请重新考虑是否真的需要它们),否则根本不需要调用它。但是,不,-O不会删除该调用。 - jonrsharpe
我刚刚开始进行单元测试,但这可能是处理计算密集型“日志记录”的更好方法,例如使用hypothesis - noumenal
@noumenal 这是用于测试,而不是日志记录,因此根本不应该成为部署的代码的一部分。通常测试位于与包本身分开的单独目录中,只有在所有测试都通过后才会部署包。测试执行的日志/输出对于生产性能来说是无关紧要的。 - jonrsharpe

2
我在这里找到了答案here
if __debug__:
    doSomething()

__debug__设置为false需要使用标志-O-OO运行Python。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接