如何将“理由”与回归价值结合起来,优雅

时间:2011-06-22 21:09:57

标签: python

在我写的代码中经常发生的事情是我将有一个函数来检查依赖于许多其他条件的条件,例如:

def is_foo(bar):
    if X: return True
    if Y: return False
    if Z: return True
    return False

然后,我想调试我的代码或记录它,所以我将上面改为:

def is_foo_reason(bar):
    if X: return True, "cause of X you fool"
    if Y: return False, "no X but Y"
    if Z: return True, "Z Z Z Z Z Z"
    return False, "default"
#for backwards compatibility:
def is_foo(bar): return is_foo_reason(bar)[0] 

然后想要原因的代码(因此可以将其记录/显示给用户,w / e)调用_reason版本。

我的问题是:还有更优雅的方法吗?

3 个答案:

答案 0 :(得分:8)

这是一个非常好的方法。我唯一可能改变的是在is_foo_reason中嵌套is_foo(因此只有一个简单的接口)并向is_foo()添加一个默认参数,例如

#for backwards compatibility:
def is_foo(bar, reason=False): 
    def is_foo_reason(bar):
        if X: return True, "cause of X you fool"
        if Y: return False, "no X but Y"
        if Z: return True, "Z Z Z Z Z Z"
        return False, "default"
    if reason:
        return is_foo_reason(bar)
    else:
        return is_foo_reason(bar)[0] 

这样,默认情况下该功能不会给出原因,但如果你想要一个,你可以要求一个。

答案 1 :(得分:4)

我认为如果只是调试,你不应该改变你的函数的语义。使用例如而是一个记录器。看一下Python的日志模块:http://docs.python.org/library/logging.html

import logging

def is_foo(bar):
    logger = logging.getLogger()
    if X:
        logger.debug("msg1")
        return True
    if Y:
        logger.debug("msg2")
        ...

然后,您可以定义日志记录处理程序,以将消息记录到文件中,或者在屏幕上打印它们等。

答案 2 :(得分:1)

为了将来可返回值的可扩展性,请使用namedtuple:

from collections import namedtuple
ExplainedValue = namedtuple('ExplainedValue', 'value explanation')

def is_foo_reason(bar):
    if X: return ExplainedValue(True, "cause of X you fool")
    if Y: return ExplainedValue(False, "no X but Y")
    if Z: return ExplainedValue(True, "Z Z Z Z Z Z")
    return ExplainedValue(False, "default")

def is_foo(bar): return is_foo_reason(bar).value