Python 如何优雅地创建自定义断言错误?

Python 如何优雅地创建自定义断言错误?,python,python-3.x,function,Python,Python 3.x,Function,我制作了一系列函数来控制基于消息的仪器。我知道如何使用它们,但这些函数应该是傻瓜式的,以防在我离开后其他人想用它来编码。下面是一个示例函数: def AutoRange(self, Function, Source, Value): """Enable or disable the instrument autoranging feature.\n :Function: "source" or "measure". :Source: "v" or "i". :Va

我制作了一系列函数来控制基于消息的仪器。我知道如何使用它们,但这些函数应该是傻瓜式的,以防在我离开后其他人想用它来编码。下面是一个示例函数:

def AutoRange(self, Function, Source, Value):
    """Enable or disable the instrument autoranging feature.\n
    :Function: "source" or "measure".
    :Source: "v" or "i".
    :Value: 0 or 1."""

    # <Something goes here to check if the inputs are valid>
    self.WRITE("smua.%s.autorange%s = %s" %(Function, Source, Value))
在阅读了
assert()
之后,我将
if
替换为:

    MyErrorMessage = "/!\ Error in Keithley.Autorange(): Input not allowed."
    assert (Function in ("source", "measure")), MyErrorMessage
    assert (Source in ("v", "i")), MyErrorMessage
    assert (Value in (0, 1)), MyErrorMessage
一个可能的更整洁的变体是:

    ValidInputs = (    Function in ("source", "measure")
                   and Source in ("v", "i")
                   and Value in (0, 1))

    assert (ValidInputs), "/!\ Error in Keithley.Autorange(): Input not allowed."

第二个选项是更好的,因为我现在想到它,因为这样我可以明确地告诉哪些输入是无效的。所以我的问题是:这就是你应该如何处理断言?1
assert()
用于1个输入?如果没有,建议的结构是什么?提前感谢。

为什么不做Python做的事情

让我们看一个例子:

open("foo", "q")
# => ValueError: invalid mode: 'q'
open
是C语言,但您可以看到它的外观,例如:

不要害怕把代码延长一点;在Python中,您无法真正避免它。而且,“Keithley.Autorange()中的错误:不允许输入。”不会告诉程序员哪些输入是不允许的。在这种情况下,明确和清晰比聪明和简短要好

我会:

def auto_range(self, function, source, value):
    if function not in ["source", "measure"]:
        raise ValueError("Invalid function: %s" % function)
    if source not in ["v", "i"]:
        raise ValueError("Invalid source: %s" % source)
    if value not in [0, 1]:
        raise ValueError("Invalid value: %d" % value)
    # ...

与您的问题不直接相关,但最好坚持该语言的编码风格:在Python中,变量采用
snake_case
(小写加下划线)。

assert
不用于此用途,请引用:“assert语句是将调试断言插入程序的一种方便方式”-您可以让Python轻松忽略带有
-O
参数的所有断言。只需以旧的方式验证输入(您可以使用验证映射保存详细信息),并在需要时引发适当的异常。至少会想到两种情况:一致性和@zwer指出的事实,即可以禁用断言检查以加速生产系统。我要说的是,对Python来说足够好的东西应该对Guimoute来说足够好:),Python不重视紧凑性。你想要简洁,去学J或者其他什么(示例:
quicksort=:($:@(#[)({-?@#))^:(1然后根据需要进行设置。如果不是0,我知道你知道:)啊,是的,对不起,我应该理解:P但是是的,这是一种非常常见的模式,你在其中放置“警卫”在函数顶部,如果所有警卫都满意,则继续使用真正的内容。@Jean-Françoisfare仔细考虑您的建议,因为这使“vi”成为一个有效的输入,不会产生错误,而只支持“v”和“i”。
if "t" in mode:
    if "b" in mode:
        raise ValueError("Invalid mode: %r" % (mode,))
def auto_range(self, function, source, value):
    if function not in ["source", "measure"]:
        raise ValueError("Invalid function: %s" % function)
    if source not in ["v", "i"]:
        raise ValueError("Invalid source: %s" % source)
    if value not in [0, 1]:
        raise ValueError("Invalid value: %d" % value)
    # ...