如何在Python中处理选项参数?(只能是一组值的参数)

如何在Python中处理选项参数?(只能是一组值的参数),python,arguments,code-readability,Python,Arguments,Code Readability,由于我缺乏术语,我很难提出这个问题。我不是在询问具有默认值的关键字参数。我的问题是如何处理只能有一组值的参数值,以及如何优化代码可读性和防止重复 请参见此函数的示例: def foo(opt='something'): 如果opt==‘某物’: ret=dowhatever() elif opt=='somethingelse': ret=dowhateverelse() 其他: 引发未识别的ArgumentException(opt) 回程网 在我看来,这是相当丑陋的。在python中,它基

由于我缺乏术语,我很难提出这个问题。我不是在询问具有默认值的关键字参数。我的问题是如何处理只能有一组值的参数值,以及如何优化代码可读性和防止重复

请参见此函数的示例:

def foo(opt='something'):
如果opt==‘某物’:
ret=dowhatever()
elif opt=='somethingelse':
ret=dowhateverelse()
其他:
引发未识别的ArgumentException(opt)
回程网
在我看来,这是相当丑陋的。在python中,它基本上是一个不太好看的java开关转换。出现的一个问题是,案例之间有公共代码(重复),我希望避免这种情况。如果我要避免这种情况,我会写:

def foo(opt='something'):
如果选择不加入['something'、'something\u other']:
引发未识别的ArgumentException
如果opt==‘某物’:
ret=做任何事()
elif opt==“其他东西”:
ret=做任何其他事情()
做一些通用的事情(ret)
如果opt==‘某物’:
ret=事后做任何事()
elif opt==“其他东西”:
ret=以后做任何事情()
回程网

这甚至更加丑陋。有没有更好的方法来编写这样的代码?

我现在重新开始这个问题(以前作为 ) 为了解决在两个系统之间使用通用代码的具体问题 相关案例类块。这与上下文管理器的概念有关。 这里,我们定义两个不同的上下文管理器,并存储它们 在一个
命令中
;case语句替换用于选择 我们将使用哪个上下文管理器

import contextlib

# Step 1: Define the context managers. Usingcontextlib.contextmanager for
# simplicity, but you can define a class with `__enter__` and `__exit__`
# methods as well.

@contextlib.contextmanager
def Something():
    yield do_whatever()
    do_whatever_afterwards()


@contextlib.contextmanager
def SomethingElse():
    yield do_whatever_else()
    do_whatever_else_afterwards()


# Step 2: Map your selectors to the context managers
cms = {
    'something': Something,
    'something_else': SomethingElse
}


# Step 3: Select a context manager and handle attempts to select a non-existent one
opt = ...  # 'something' or 'something_else'
try:
    cm = cms[opt]
except KeyError:
    raise UnrecognisedArgumentException(opt)

# Step 4: Run your universal code in the correct context
with cm() as x:
    do_something_universal(x)

我将重新打开此问题(以前作为副本关闭) ) 为了解决在两个系统之间使用通用代码的具体问题 相关案例类块。这与上下文管理器的概念有关。 这里,我们定义两个不同的上下文管理器,并存储它们 在一个
命令中
;case语句替换用于选择 我们将使用哪个上下文管理器

import contextlib

# Step 1: Define the context managers. Usingcontextlib.contextmanager for
# simplicity, but you can define a class with `__enter__` and `__exit__`
# methods as well.

@contextlib.contextmanager
def Something():
    yield do_whatever()
    do_whatever_afterwards()


@contextlib.contextmanager
def SomethingElse():
    yield do_whatever_else()
    do_whatever_else_afterwards()


# Step 2: Map your selectors to the context managers
cms = {
    'something': Something,
    'something_else': SomethingElse
}


# Step 3: Select a context manager and handle attempts to select a non-existent one
opt = ...  # 'something' or 'something_else'
try:
    cm = cms[opt]
except KeyError:
    raise UnrecognisedArgumentException(opt)

# Step 4: Run your universal code in the correct context
with cm() as x:
    do_something_universal(x)

通常,当使用不允许的值时,您会引发
ValueError
。我会使用类似
{'something':dowhatever,'somethingelse':dowhateverelse}
的dict。根据一个参数,一个行为可以任意不同的函数首先应该是两个函数。你的第二个问题说明了定义两个独立的上下文管理器的理由,在这两个上下文管理器中,
something.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu=do\uuuuuuuuuuu where
something.\uuuuuuuuuuu,但是想象一下,代码块要大得多,而不是一个函数。这个例子只是为了illustrate@James是的,我知道,这只是为了举例说明,当使用不允许的值时,通常会引发
ValueError
。我会使用类似
{'something':dowhatever,'somethingelse':dowhateverelse}
的命令。根据一个参数,一个行为可以任意不同的函数首先应该是两个函数。你的第二个问题说明了定义两个独立的上下文管理器的理由,在这两个上下文管理器中,
something.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu=do\uuuuuuuuuuu where
something.\uuuuuuuuuuu,但是想象一下,代码块要大得多,而不是一个函数。这个例子只是为了illustrate@James是的,我知道,这只是为了插画,谢谢!很好的例子。我很困惑,因为“副本”没有我想要的答案。是的,谢谢!很好的例子。我很困惑,因为“副本”没有我想要的答案。