函数返回不同的类型是不好的做法吗?

时间:2019-05-17 01:56:42

标签: python function

假设我们有一个检测3的倍数的函数。

t1 = (1, 2, 5)
t2 = (3, 6, 9)

def find3(t):
    return [x for x in t if not x % 3] or None

我最初的倾向是,如果传入None,则返回t1;如果传入[3, 6, 9],则返回t2,如果在任何专业编程环境中都无法使用,

但是,我已经看到很多人说函数应该总是返回相同的类型。这意味着返回[]而不是None

[]不仅占用更多内存,而且似乎也不太清楚。如果我在数据集上调用find3(),并且没有倍数,我宁愿看到单词None而不是空列表,因为它更像现实生活中的语言。

是的,我知道如果在不同的位置使用find3()的结果可能会导致问题,但是问题的消失只需进行简单的if find3()检查即可。那么为什么/在所有情况下最好返回[]

2 个答案:

答案 0 :(得分:2)

经验法则

赋予某种搜索功能...

找不到单个元素应返回None;

如果找不到任何预期会出现的元素,则应返回[]

说明

某些内置方法,例如re.search返回None表示某种形式的否定或失败,在这种情况下,表示未找到

尽管在您的特定情况下,由于否定falsy可以完美地由空列表[]表示,所以返回None并没有好处。

等效于re.search的列表re.findall就是这样做的。如果没有匹配项,它将返回[]

甚至有实际的原因不返回None。考虑这段代码...

for x in find3([1, 2, 4]):
    ...

这将引发一个TypeError,这是违反直觉的,您必须通过撤消该函数的操作来对其进行修复。

for x in find3([1, 2, 4]) or []:
    ...

这表明返回None比这里的事情更痛苦。

答案 1 :(得分:1)

None相比,我个人更喜欢空列表,嗯,我不能这么说,这取决于问题所在。

为什么我应该有一个[](空列表)?

通常,在此之后您需要执行一些操作时,假设我们要append额外的值。

使用None

def find3(t):
    return [x for x in t if not x % 3] or None
l = find3(t1)
l.append(1)
print(l)

输出:

AttributeError: 'NoneType' object has no attribute 'append'

使用[]

def find3(t):
    return [x for x in t if not x % 3]
l = find3(t1)
l.append(1)
print(l)

输出:

[1]

如您所见,None会给您一个错误。

而且,通过获得[]的输出,您可以获得更简洁的代码。

我为什么要拥有None

通常,当您使用一个简单的功能(如您所展示的)完成代码时,就可以更清楚地看到代码的用户(我的意思是用户是从未编码的人)。

两种方法都可以执行相同的语句并通过:

def find3(t):
    return [x for x in t if not x % 3] or None
l = find3(t1)
if l:
    print('Success')

并且:

def find3(t):
    return [x for x in t if not x % 3]
l = find3(t1)
if l:
    print('Success')

此外,对于append,您可以执行以下操作:

def find3(t):
    return [x for x in t if not x % 3] or None
l = find3(t1) or []
l.append(1)
print(l)

输出:

[]

or很神奇...

摘要:

最后,这是您的全部决定(正如SO所描述的那样,主要是基于意见的),您可以决定所需的内容,没有人会在意(当您不公开展示时)代码的灾难性,如果可以,那么就可以,如果不能,就可以。