在Function中只允许一个True参数

时间:2015-06-23 04:47:31

标签: python validation arguments

给出以下功能:

def controls_validation(creation_mode=False, existence_mode=False, integrity_mode=False):
    if creation_mode:
        # Do X
    elif existence_mode:
        # Do Y
    elif integrity_mode:
        # Do Z
    else:
        raise ValueError("At least one arg required.")

我想验证参数,以便只允许一个True参数。当然,我的else / elif语句有一个特定的顺序,我不希望用户例如设置" creation_mode"和" integrity_mode"为了真实,因此有了这个功能,快乐地做X只是因为"创造模式"首先,即使某些事情显然是错误的,但该功能可能无法验证用户打算验证的模式。

我已经读过,验证参数不是你应该在Python中做的事情,除非你有一个非常具体的原因。我应该打扰这个吗?或者,用户有责任阅读文档并知道如何使用它吗?

提前感谢您的意见。

3 个答案:

答案 0 :(得分:2)

当我们说您不想对输入进行验证时,我们的想法是您可以重新组织代码,这样大多数验证都不是必需的。例如,假设您将其拆分为3个函数,例如下面的函数。

def create_mode():
    # Do X

def existence_mode():
    # Do Y

def integrity_mode():
    # Do Z

由于函数的名称,以及它们必须通过名称显式调用函数的事实,它们不太可能传递错误的参数。因此,需要很少的验证。事实上,对于这个例子,似乎根本没有参数,所以零验证。

答案 1 :(得分:1)

这会更接近你正在寻找的东西:

def controls_validation(creation_mode=False, existence_mode=False, integrity_mode=False):
    if creation_mode and not existence_mode and not integrity_mode:
        print("creation")
    elif existence_mode and not creation_mode and not integrity_mode:
        print("existence")
    elif integrity_mode and not creation_mode and not existence_mode:
        print("integrity")
    else:
        raise ValueError("At least one arg required.")

这将确保只有一个arg输入为true而其他arg为false。

我会考虑使用tryexcept,因此在输入错误时它不会终止程序。这一切都取决于您是否在执行时寻找用户的直接输入。

如果你想要一些更具伸缩性的东西,那么你可以从这开始并改进它。

def controls_validation(mode):
    modes = ['creation_mode', 'existence_mode', 'integrity_mode']
    check = mode.split()
    count = 0
    for w in check:
        count += 1
    if count == 1:
        if mode == 'creation_mode':
            print('creation_mode')
        elif mode == 'existence_mode':
            print('existence_mode')
        elif mode == 'integrity_mode':
            print('integrity_mode')
        else:
            pass
    else:
        raise ValueError("At least one arg required.")

再次压缩:

def controls_validation(mode):
    m = ['creation_mode', 'existence_mode', 'integrity_mode']
    check = mode.split()
    if len([v for v in check if mode in m]) is 1:
        if mode == 'creation_mode':
            print('creation_mode')
        elif mode == 'existence_mode':
            print('existence_mode')
        elif mode == 'integrity_mode':
            print('integrity_mode')
        else:
            pass
    else:
        raise ValueError("At least one arg required.")

答案 2 :(得分:0)

您可以采取以下两种可能的方法。

第一个示例确保通过将模式作为单个参数传递,只能执行一种模式。这将使将来更容易添加更多模式。

creation_mode = 1
existence_mode = 2
integrity_mode = 3

def controls_validation_v2(mode):

    if mode == creation_mode:
        print("creation")
    elif mode == existence_mode:
        print("existence")
    elif mode == integrity_mode:
        print("integrity")
    else:
        raise ValueError("invalid mode")

controls_validation_v2(creation_mode)

第二种方法不太明显。布尔变量确实等于0或1,因此可以使用这个值来总计它们的值,以确保总数正好为1.除非代码被更改,否则永远不应达到raise

def controls_validation_v3(creation_mode=False, existence_mode=False, integrity_mode=False):

    if creation_mode + existence_mode + integrity_mode != 1:
        print("only one true argument is allowed")
    elif creation_mode:
        print("creation")
    elif existence_mode:
        print("existence")
    elif integrity_mode:
        print("integrity")
    else:
        raise ValueError("At least one arg required.")