7

是否应使用相同的数据类型从函数返回或分配默认值?还是没有?什么是更好的编码实践,为什么?

例如。python中的一些伪代码:

/1

def my_position():   # returns a positive integer if found
    if(object is present):
          position = get_position()
          return position # eg 2,3,4,6
    else: 
          return None     # or return -1 or 0 ??

/2

def get_database_rows():    
    do query to whatever database
    if(rows are found):
       return [list of rows]
    else:
       return None  # or return empty list []  ?

/3

the_dictionary = {'a' : 'john','b':'mike','c': 'robert' }  # values are names i.e. non empty string
my_new_var = the_dictionary.get('z', None)  # or the_dictionary.get('z','')  ?
4

6 回答 6

8
  1. IndexError如果未找到该项目,则引发。这就是 Pythonlist所做的。(或者在进行二分搜索或类似操作时,可能会返回该项目应该存在的索引。)

  2. 从逻辑上考虑你的函数做了什么:如果它返回一个数据库中满足某个标准的所有项目的列表,并且没有这样的项目,那么返回一个空列表是有意义的,因为它允许所有常见的列表操作(len, in) 无需显式检查即可运行。

    但是,如果所需项目的缺失表明不一致,则引发异常。

  3. 我之前的评论特别适用于这种情况:这取决于您将如何处理您获得的价值。当找不到密钥时,普通函数dict只会引发 a 。KeyError您正在用一个值替换该异常,因此您应该知道哪个值在您的程序上下文中是有意义的。如果没有值,那么就让异常飞起来。

也就是说,返回None通常是一个坏主意,因为它可能会掩盖错误。None是 Python 中的默认返回值,因此返回它的函数可能仅表明其作者忘记了一条return语句:

def food(what):
    if what == HAM:
        return "HAM!"
    if what == SPAM:
        return " ".join(["SPAM" for i in range(10)])
    # should raise an exception here

lunch = food(EGGS)    # now lunch is None, but what does that mean?
于 2013-01-29T13:15:28.663 回答
1

案例 1:引发 IndexError。

基本原理:返回 -1 是 C 风格,而IndexErrorraise 则更 Pythonic。

案例2:返回空列表。

理由:避免不必要的空检查。也可参考《Effective Java(2ed) Item43 Return empty arrays or collections, not nulls 》一书(没错,是Java,但参数仍然有效)

案例3:取决于。

理由:如果你不想 raise KeyError,是空字符串还是None取决于实际需要,但要注意两点:第一,保持一致,不要混用None和空字符串互换;其次,确保空字符串与有效值区分开来(即有效值不能为空),如果有疑问,请None改用。

于 2013-01-29T13:26:28.080 回答
1

问题中还没有列出另一个选项:抛出异常。它似乎在 python 中足够流行,有时最好遵循您的语言的常见做法,而不是寻找抽象的最佳解决方案。

至于你的例子:

  1. 我会考虑-1因为那是什么"".find,或者抛出 aValueError因为那是什么[].index(我并不是说第一个选项是最好的)。我永远不会使用基于 1 的索引,因此该值0是有效结果,不能用于表示空值。

  2. 我更喜欢一个空列表,因为不能保证调用者对作为一种特殊情况感兴趣。如果我想计算多个查询的所有行,我不想None专门处理。如果存在无法生成行列表的逻辑上不同的情况(与没有匹配的行相反),我会考虑使用None或抛出这种情况下的异常。

  3. 示例的含义不清楚,特别是考虑到它None是有效的字典键。但是如果我必须在通常需要字符串的地方使用一些特殊值,我会更喜欢它None(如果你更喜欢空字符串,重要的是要确定你永远不需要一个有效的空字符串,除了它本身之外没有什么特别的东西)。

于 2013-01-29T13:27:49.337 回答
1

例外通常是首选,但如果你不想使用它们,这真的取决于你想要什么。

当在列表中请求不存在的项目的索引时,返回None可能与返回一样好,-1因为该查询没有可能的好答案。调用该函数后,我必须检查它是否可以产生结果,然后再继续处理结果。

Bu 当询问列表中所有奇数的列表时,您应该返回[]而不是None因为[]是一个完全有效的答案。我可能想知道我在原始列表中有多少个奇数,如果它是空的,0 是我需要的答案,所以类似于

len(odd_numbers(lst))

应该总是工作。在那种情况下返回None将是棘手且容易出错的,就像我必须做的那样

0 if odd_numbers(lst) is None else len(odd_numvers(lst))
于 2013-01-29T13:30:50.793 回答
0

在这种情况下,我认为空列表更好,但我认为这个问题没有“一般”的答案:它通常取决于情况。绝对要避免的一件事 — 返回的值类型多于 ine 类型(None 除外)。我看过代码,其中函数 coulr 返回:string、None、bool、1、2 和 3。那是一种威胁。

于 2013-01-29T13:11:31.040 回答
0

这些情况是不同的。

1 -return position # eg 2,3,4,6

这就像一个记录,所以None对我来说很有意义。(或者,正如其他人所提到的,如果你总是希望有一个职位,那么就提出一个例外。)

2 -return [list of rows]

这是一个行列表,因此返回[]是合乎逻辑的,您不必特殊情况迭代结果,您可以使用for row in rows:.

3 - `the_dictionary = {'a' : 'john','b':'mike','c': 'robert' }

再次,这看起来像一个记录,所以缺失值自然是None(通常)。(如果你总是希望有一本字典,那就提出一个例外)。

于 2013-01-29T13:12:26.047 回答