如果我有一个需要从列表中返回n
随机元素的函数,我可能想检查列表中元素的数量是否大于我要求的样本数量,是:
mysample = []
def rnd(n):
if len(mysample) < n:
return False
return random.sample(mysample, n)
在这种情况下,如果要求的元素数量大于我们的数量,则返回False
。
这是好习惯吗?我们正在调用rnd()
的地方期待返回一个列表,而不是布尔值,所以它对我来说并不合适。
答案 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
任何数字类型的零,例如
0
,0.0
,0j
。任何空序列,例如
''
,()
,[]
。任何空映射,例如
{}
。
答案 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