如何指定无法访问的python代码

时间:2009-05-02 18:16:07

标签: python

在python中指定无法访问的代码的pythonic方法是什么,如:

gender = readFromDB(...) # either 'm' or 'f'
if gender == 'm':
    greeting = 'Mr.'
elif gender == 'f':
    greeting = 'Ms.'
else:
    # What should this line say?

7 个答案:

答案 0 :(得分:25)

raise ValueError('invalid gender %r' % gender)

答案 1 :(得分:7)

这取决于您对性别的确定程度为'm''f'

如果您完全确定,请使用if...else代替if...elif...else。只是让每个人都更容易。

但是,如果数据格式错误,您应该提出异常,以便更轻松地进行测试和修复错误。在这种情况下,你可以使用性别中立的问候语,但是对于任何更大的问题,特殊值只会让bug更难找到。

答案 2 :(得分:7)

你可以提出异常:

raise ValueError("Unexpected gender; expected 'm' or 'f', got %s" % gender)

如果您希望数据库只返回“m”或“f”,则使用断言False:

assert False, "Unexpected gender; expected 'm' or 'f', got %s" % gender

答案 3 :(得分:5)

我实际上认为这是个好地方。

class SeriousDesignError(Exception):
    pass

所以你可以这样做

if number % 2 == 0:
    result = "Even"
elif number % 2 == 1:
    result = "Odd"
else:
    raise SeriousDesignError()

我认为这是最有意义的错误消息。这种事情只能通过设计错误(或糟糕的维护,这是同一件事)来实现。

答案 4 :(得分:4)

这完全取决于您希望错误发出信号,但在这种情况下我会使用字典:

greetings = {'m': 'Mr.', 'f': 'Ms.'}
gender = readFromDB(...)  # either 'm' or 'f'
greeting = greetings[gender]

如果性别既不是m也不是f,这将引发包含意外值的KeyError:

greetings = {'m': 'Mr.', 'f': 'Ms.'}

>>> greetings['W']

Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    greetings['W']
KeyError: 'W'

如果您想在邮件中获得更多详细信息,您可以抓住&amp;重新加注:

try:
    greeting = greetings[gender]
except KeyError,e:
    raise ValueError('Unrecognized gender %s' % gender)

答案 5 :(得分:3)

到目前为止,我通常使用John Fouhy答案的变体 - 但这并不完全正确,正如Ethan指出的那样:

assert gender in ('m', 'f')
if gender == 'm':
    greeting = 'Mr.'
else:
    greeting = 'Ms.'

使用断言的主要问题是,如果有人使用-O或-OO标志运行您的代码,则断言会被优化掉。正如Ethan在下面指出的那样,这意味着你现在根本没有数据检查。断言是一种开发辅助工具,不应用于生产逻辑。我将养成使用check()函数的习惯 - 这允许干净的调用语法,如断言:

def check(condition, msg=None):
    if not condition:
        raise ValueError(msg or '')

check(gender in ('m', 'f'))
if gender == 'm':
    greeting = 'Mr.'
else:
    greeting = 'Ms.'

回到最初的问题,我声称在if / else逻辑之前使用assert()或check()更容易阅读,更安全,更明确:

  • 它在开始对其采取行动之前先测试数据质量 - 如果在if / else链中有“==”以外的运算符,这可能很重要
  • 它将断言测试与分支逻辑分开,而不是交错它们 - 这使得阅读和重构更容易

答案 6 :(得分:2)

我有时会这样做:

if gender == 'm':
    greeting = 'Mr.'
else:
    assert gender == 'f'
    greeting = 'Ms.'

我认为这可以很好地告诉读者代码只有(在这种情况下)两种可能性,以及它们是什么。虽然您可以提出一个比AssertionError更具描述性错误的案例。