在期望非bool返回值时返回False是一种好习惯吗?

时间:2017-01-15 17:37:31

标签: python python-3.x

如果我有一个需要从列表中返回n随机元素的函数,我可能想检查列表中元素的数量是否大于我要求的样本数量,是:

mysample = []

def rnd(n):
    if len(mysample) < n:
        return False
    return random.sample(mysample, n)

在这种情况下,如果要求的元素数量大于我们的数量,则返回False

这是好习惯吗?我们正在调用rnd()的地方期待返回一个列表,而不是布尔值,所以它对我来说并不合适。

3 个答案:

答案 0 :(得分:6)

实际上没有必要这样做,random.sample does it for you (see end of its documentation)

  

如果样本量大于人口规模,则会引发ValueError

但是,为了回答你的问题,你通常希望在这些情况下引发异常,而不是返回一些东西。如果不这样做,用户将不会总是意识到实际发生了错误(并且错误永远不会无声地传递)。

答案 1 :(得分:1)

mysample = []

def rnd(n):
    if len(mysample) < n:
        return []
    return random.sample(mysample, n)

只需返回一个空列表,当您需要检查时,请使用:

if rnd():
    pass
  

可以测试任何对象的真值,以便在if或while中使用   条件或下面的布尔运算的操作数。下列   值被视为错误:

     

None

     

False

     

任何数字类型的零,例如00.00j

     

任何空序列,例如''()[]

     

任何空映射,例如{}

答案 2 :(得分:1)

在Jim Fasarakis-Hilliard的回答中稍微扩展一下......

在特殊情况下返回特殊值很容易出错,因为任何调用函数的代码都必须防范特殊情况:

x = rnd(n)
if x == False:
    # deal with it
else:
    # do what you wanted to in the first place

请注意,如果False是您的特殊值,则不能只说if not x: ...,因为这会捕获一个空列表,这是“通常”情况下的有效返回值。像这样的细微差别在特殊返回值中很常见,你不能假设调用代码总是会预期它们。

如果主叫代码忽略了防范您的特殊值,则错误变得更难追踪:

x = rnd(n)
#
# ... do some stuff ...
#
y = len(x)  # Aargh, TypeError ... where did that happen?

如果您引发异常:

def rnd(n):
    if len(mysample) < n:
        raise ValueError('n must be no larger than size of mysample')
    return random.sample(mysample, n)

...调用rnd()时会发生任何错误,并显示有用的错误消息。如果需要防范特殊情况,那么这样做的代码更明确(并且不太容易出现细微的边缘情况):

try:
    x = rnd(n)
except ValueError:
    # deal with it
# all is well, continue as normal