Python 编码练习:返回 None 和返回相同数据类型的空值?
函数返回值和默认值应该使用相同的数据类型吗?还是可以用None?哪种写法更好呢?为什么?
比如,下面是一些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','') ?
6 个回答
还有一个问题中没有提到的选项:抛出异常。在Python中,这种做法似乎挺流行的,有时候遵循你所用语言的常见做法比寻找一个抽象的“最佳”解决方案要好。
关于你的例子:
我会考虑用
-1
,因为这和“”.find
的做法一致,或者抛出一个ValueError
,因为这就是[].index
的做法(我并不是说第一个选项是最好的)。我从来不使用从1开始的索引,所以0
是一个有效的结果,不能用来表示“空”。我更倾向于返回一个空列表,因为调用者不一定会把“空”当作一个特殊情况。如果我想统计多个查询的所有行,我不想特别处理
None
。如果有一种逻辑上不同的情况,导致行列表“无法生成”(与“没有匹配的行”不同),我会考虑在这种情况下使用None
或抛出异常。一个例子的含义不太清楚,尤其是考虑到
None
是一个有效的字典键。但如果我“必须”在通常期望字符串的地方使用某个特殊值,我会更倾向于使用None
(如果你更喜欢空字符串,重要的是要确保你绝对不需要一个“有效的空字符串”,它只代表它自己,没有其他特殊含义)。
一般来说,使用异常处理是比较好的选择,但如果你不想用,那就得看你具体想要什么了。
比如,当你在一个列表中查找一个不存在的项目的索引时,返回 None
和返回 -1
其实差不多,因为这个问题本身就没有好的答案。在调用这个函数后,我必须先检查它是否能给出结果,然后才能继续处理这个结果。
但是,当你想要获取列表中所有奇数的列表时,应该返回 []
而不是 None
,因为 []
是一个完全有效的答案。我可能想知道原始列表中有多少个奇数,如果没有奇数,那答案就是0,所以像这样
len(odd_numbers(lst))
总是能正常工作。在这种情况下返回 None
会很麻烦,也容易出错,因为我还得做
0 if odd_numbers(lst) is None else len(odd_numvers(lst))
如果找不到某个项目,就抛出一个
IndexError
错误。这是Python的list
的做法。(或者在进行二分查找等操作时,可以返回这个项目应该在的位置索引。)想想你的函数逻辑上是做什么的:如果它返回的是数据库中所有满足某个条件的项目的列表,而没有这样的项目,那么返回一个空列表是合理的,因为这样可以让所有常用的列表操作(比如
len
和in
)正常工作,而不需要额外的检查。但是,如果缺少这些项目意味着数据不一致,那么就应该抛出一个异常。
我之前的说法特别适用于这种情况:这取决于你打算怎么处理你得到的值。普通的
dict
在找不到键时会抛出KeyError
错误。你用一个值来替代这个异常,所以你应该知道在你的程序上下文中哪个值是合适的。如果没有合适的值,那就让异常抛出来吧。
不过,返回None
通常是个坏主意,因为这可能会掩盖错误。None
是Python中的默认返回值,所以一个返回None
的函数可能只是因为作者忘记写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?