返回元组或 None 的函数:如何很好地调用该函数?

发布于 2024-09-13 20:36:24 字数 417 浏览 5 评论 0原文

假设如下:

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

我不喜欢的是我必须使用单个变量然后将其解压。

另一个解决方案是我可以让函数返回一个充满 None 的元组,以便调用者可以很好地解压......

任何人都可以提出更好的设计吗?

Suppose the following:

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

What is the best way to define a function that returns a tuple and yet can be nicely called. Currently, I could do this:


r = MyFunc()
if r:
  v1, v2, v3 = r
else:
  # bad!!
  pass

What I don't like about this is that I have to use a single variable and then unpack it.

Another solution is I could have the function return a tuple full of Nones so that the caller can nicely unpack....

Anyone can suggest a better design?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

百合的盛世恋 2024-09-20 20:36:24

引发一个ArgumentError怎么样?然后您可以尝试调用它,并在参数错误时处理异常。

所以,类似:

try:
    v1, v2, v3 = MyFunc()
except ArgumentError:
    #deal with it

另外,请参阅 katrielalex 对于使用 ArgumentError 子类的回答

How about raise an ArgumentError? Then you could try calling it, and deal with the exception if the argument is wrong.

So, something like:

try:
    v1, v2, v3 = MyFunc()
except ArgumentError:
    #deal with it

Also, see katrielalex's answer for using a subclass of ArgumentError.

七分※倦醒 2024-09-20 20:36:24

这应该可以很好地工作:

v1, v2, v3 = MyFunc() or (None, None, None)

MyFunc()返回一个元组时,它将被解包,否则它将被替换为None的3元组。

This should work nicely:

v1, v2, v3 = MyFunc() or (None, None, None)

When MyFunc() returns a tuple, it will be unpacked, otherwise it will be substituted for a 3-tuple of None.

熟人话多 2024-09-20 20:36:24

recursive 有一个真正优雅且Pythonic 的解决方案。但是:为什么要返回 None ? Python 有一种处理错误的方法,那就是引发异常:

class AIsTooSmallError( ArgumentError ): pass

然后

raise AIsTooSmallError( "a must be positive." )

这种方法更好的原因是返回一个值表明您已完成处理并正在传回您的答案。如果您已经完成了一些处理,这很好,但如果您立即返回 None,那就很愚蠢了。

recursive has a truly elegant and Pythonic solution. BUT: why do you want to return None? Python has a way of handling errors, and that is by raising an exception:

class AIsTooSmallError( ArgumentError ): pass

and then

raise AIsTooSmallError( "a must be positive." )

The reason this is better is that returning a value indicates that you have completed processing and are passing back your answer. This is fine if you have done some processing, but it's silly if you are immediately returning None.

少跟Wǒ拽 2024-09-20 20:36:24

另一个解决方案是我可以让函数返回一个充满 None 的元组,以便调用者可以很好地解压......

这有什么问题?一致性是一件好事。

Another solution is I could have the function return a tuple full of Nones so that the caller can nicely unpack....

What's wrong with that? Consistency is a good thing.

长伴 2024-09-20 20:36:24

如果您希望 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 模块的 code> 函数。它在某种程度上介于前两种情况之间,因为匹配失败是预期结果,而默认返回对象无论如何都不是很有用。

If you want the v1, v2, v3 objects to exist and be set to a default value in the case of an error, return the default values yourself. This will make the calling code simpler by not relying on the caller to set them manually:

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)

On the other hand, if a default return is not appropriate and a negative argument is considered a serious error, raise an exception:

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)

On the third hard, returning None may be preferable sometimes when returning a single object, as is the case with the search() and match() functions of the re module. It somehow stands between the first two cases, because matching failure is an expected outcome, while a default return object wouldn't be very useful anyway.

烧了回忆取暖 2024-09-20 20:36:24

这与之前的答案类似。您可以返回一个对象实例或 None

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

This is similar to the previous answer. You could return either an object instance or None

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文