代码之家  ›  专栏  ›  技术社区  ›  Elias Bachaalany

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

  •  13
  • Elias Bachaalany  · 技术社区  · 14 年前

    假设如下:

    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的元组,这样调用者就可以很好地解包了。。。。

    有人能提出更好的设计吗?

    6 回复  |  直到 14 年前
        1
  •  12
  •   Community Egal    7 年前

    ArgumentError ? 那你就可以了 try 调用它,如果参数是错误的,则处理异常。

    比如说:

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

    另外,请参见 katrielalex's answer 使用ArgumentError的子类。

        2
  •  10
  •   recursive    14 年前

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

    什么时候? MyFunc() 返回一个元组,它将被解包,否则它将被替换为 None .

        3
  •  8
  •   Katriel    14 年前

    recursive 有一个真正优雅和蟒蛇解决方案。但是:你为什么要回来 None

    class AIsTooSmallError( ArgumentError ): pass
    

    然后

    raise AIsTooSmallError( "a must be positive." )
    

    这样做更好的原因是,返回一个值表示您已经完成了处理,并且正在传回您的答案。这是好的,如果你做了一些处理,但它是愚蠢的,如果你立即返回 .

        4
  •  4
  •   S.Lott    14 年前

    另一个解决方案是我可以让函数返回一个充满none的元组,这样调用者就可以很好地解包了。。。。

    怎么了?始终如一是件好事。

        5
  •  1
  •   efotinis    14 年前

    如果你想要 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 模块。它在某种程度上介于前两种情况之间,因为匹配失败是一种预期的结果,而默认返回对象无论如何都不会非常有用。

        6
  •  1
  •   Rajesh    9 年前

    这与前面的答案相似。可以返回对象实例,也可以不返回

    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