强制执行特定值列表的参数

use*_*927 12 python function

什么是pythonic方法来强制函数为给定参数获取一组特定的值?例如,有一个功能:

def results(status,data):
Run Code Online (Sandbox Code Playgroud)

我想将参数'status'限制为一组值,如0,1或99.

Zer*_*eus 10

你需要检查函数内部的值:

def results(status, data):
    valid = {0, 1, 99}
    if status not in valid:
        raise ValueError("results: status must be one of %r." % valid)
Run Code Online (Sandbox Code Playgroud)

这里valid是一个集合,因为我们唯一关心的是是否status是集合的成员(例如,我们对订单不感兴趣).为避免每次使用该函数时重新创建集合,您可能将其定义为"常量" 1全局:

VALID_STATUS = {0, 1, 99}

def results(status, data):
    if status not in VALID_STATUS:
        raise ValueError("results: status must be one of %r." % VALID_STATUS)
Run Code Online (Sandbox Code Playgroud)

用法示例:

>>> results(7, [...])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in results
ValueError: results: status must be one of {0, 1, 99}.
Run Code Online (Sandbox Code Playgroud)

总是尝试尽可能地提出最合适的例外 - 例如,ValueError告诉调用者函数发生了什么比Exception这更好.


1它并不是真正的常量,但按照惯例,ALL_UPPERCASEPython中的变量名称被认为是常量.


小智 6

例如,另一种选择是使用枚举

from enum import IntEnum

class STATUSES(IntEnum):
    ZERO = 0
    ONE = 1
    OTHER = 99

def results(status, data):
    status = STATUS(status)
Run Code Online (Sandbox Code Playgroud)

调用STATUS(status)会引发ValueError与其他答案类似的问题,但通过这种方法,您有一些好处:

  1. 添加类型注释status:STATUSES将使其他人更容易获取有效字段集(尤其是在使用 IDE 时)
  2. 您可以STATUSES以人类可读的格式命名(没有此特定用例的更广泛上下文)


jra*_*rez 5

如果status是有效值,您可以在函数内检查,如果不是,则引发异常.

def results(status,data):
    list_valid_status = [0, 1, 99]
    # list_valid_status = (0, 1, 99) # could be a tuple so it doesn't get modified by accident
    if status not in list_valid_status:
        raise ValueError("Wrong status")
Run Code Online (Sandbox Code Playgroud)

  • 另外,集合是“{0, 1, 99}” - “(0, 1, 99)”是一个元组(使用集合的原因是“in”成员资格测试对于集合来说更快,而不是它不会被修改)。 (3认同)