假设以下内容:
def MyFunc(a):
if a < 0:
return None
return (a+1, a+2, a+3)
v1, v2, v3 = MyFunc()
# Bad ofcourse, if the result was None
定义一个返回元组的函数的最佳方法是什么,但是可以很好地调用它。目前,我可以这样做:
r = MyFunc()
if r:
v1, v2, v3 = r
else:
# bad!!
pass
我不喜欢这个是我必须使用单个变量然后解压缩它。
另一个解决方案是我可以让函数返回一个充满Nones的元组,这样调用者就可以很好地解压....
任何人都可以建议更好的设计?
答案 0 :(得分:12)
如何提高ArgumentError
?然后你可以try
调用它,并在参数错误时处理异常。
所以,比如:
try:
v1, v2, v3 = MyFunc()
except ArgumentError:
#deal with it
另外,请参阅katrielalex's answer以了解使用ArgumentError的子类。
答案 1 :(得分:10)
这应该很好用:
v1, v2, v3 = MyFunc() or (None, None, None)
当MyFunc()
返回一个元组时,它将被解压缩,否则将替换为None
的3元组。
答案 2 :(得分:8)
recursive
拥有真正优雅的Pythonic解决方案。但是:你为什么要退回None
? Python有一种处理错误的方法,那就是引发异常:
class AIsTooSmallError( ArgumentError ): pass
然后
raise AIsTooSmallError( "a must be positive." )
更好的原因是返回一个值表示您已完成处理并且正在传回您的答案。如果您已经完成了一些处理,这很好,但如果您立即返回None
则很愚蠢。
答案 3 :(得分:4)
另一个解决方案是我可以让函数返回一个充满Nones的元组,这样调用者就可以很好地解压....
这有什么问题?一致性是一件好事。
答案 4 :(得分:1)
如果您希望v1, v2, v3
个对象存在并在出现错误时设置为默认值,请自行返回默认值。这将使调用代码变得更简单,而不依赖于调用者手动设置它们:
def MyFunc(a):
if a < 0:
# can't use a negative value; just return some defaults
return (None, None, None)
return (a+1, a+2, a+3)
另一方面,如果默认返回不合适且负参数被认为是严重错误,则引发异常:
def MyFunc(a):
if a < 0:
# sorry, negative values are unacceptable
raise ValueError('cannot accept a negative value')
return (a+1, a+2, a+3)
在第三个硬盘上,有时返回单个对象时返回None
可能更合适,就像search()
和match()
函数的情况一样re
模块。它以某种方式介于前两种情况之间,因为匹配失败是预期的结果,而默认的返回对象无论如何都不会非常有用。
答案 5 :(得分:1)
这与之前的答案类似。您可以返回对象实例或无
def MyFunc(a):
class MyFuncClass(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
if a < 0:
return None
return MyFuncClass(one=a+1, two=a+2, three=a+3)
o = MyFunc(1)
if o is not None:
print o.one, o.two, o.three