python是一个函数返回多个值吗?

在Python中,你可以有一个函数返回多个值。 这是一个人为的例子:

def divide(x, y): quotient = x/y remainder = x % y return quotient, remainder (q, r) = divide(22, 7) 

这看起来很有用,但看起来也可能被滥用(“Well..function X已经计算了我们需要的中间值,让我们让X返回值)”。

什么时候应该画线并定义一个不同的方法?

绝对(你提供的例子)。

元组是Python中的一等公民

有一个内置函数divmod()就是这样做的。

 q, r = divmod(x, y) # ((x - x%y)/y, x%y) Invariant: div*y + mod == x 

还有其他的例子: zipenumeratedict.items

 for i, e in enumerate([1, 3, 3]): print "index=%d, element=%s" % (i, e) # reverse keys and values in a dictionary d = dict((v, k) for k, v in adict.items()) # or d = dict(zip(adict.values(), adict.keys())) 

顺便说一下,大部分时间都不需要括号。 引用来自Python库参考 :

元组由逗号运算符 (不包括在方括号内) 构造 ,带或不带括号括起来,但空元组必须带有括号,如a,b,c或()。 单个项目元组必须有一个尾随逗号,如(d,)。

函数应该为单一目的服务

因此他们应该返回一个单一的对象。 在你的情况下,这个对象是一个元组。 考虑元组作为ad-hoc组合数据结构。 有几种语言几乎每个函数都返回多个值(Lisp中的列表)。

有时返回(x, y)而不是Point(x, y)就足够了。

命名元组

随着在Python 2.6中引入命名元组,最好在许多情况下返回命名元组而不是简单的元组。

 >>> import collections >>> Point = collections.namedtuple('Point', 'x y') >>> x, y = Point(0, 1) >>> p = Point(x, y) >>> x, y, p (0, 1, Point(x=0, y=1)) >>> px, py, p[0], p[1] (0, 1, 0, 1) >>> for i in p: ... print(i) ... 0 1 

首先,请注意,Python允许以下(不需要括号):

 q, r = divide(22, 7) 

关于你的问题,无论哪种方式都没有硬性规定。 对于简单的(通常是人为的)例子来说,一个给定的函数总是可能有一个单一的目的,导致一个单一的值。 但是,在真实应用程序中使用Python时,很快就会遇到许多需要返回多个值的情况,并导致代码更简洁。

所以,我会说做任何有意义的事情,不要试图去符合人为的惯例。 Python支持多个返回值,所以在适当的时候使用它。

你给的例子实际上是一个叫做divmod的python内build函数。 所以某个人在某个时候认为Python的核心function是足够的。

对我来说,如果它使代码更清洁,那就是pythonic。 比较这两个代码块:

 seconds = 1234 minutes, seconds = divmod(seconds, 60) hours, minutes = divmod(minutes, 60) seconds = 1234 minutes = seconds / 60 seconds = seconds % 60 hours = minutes / 60 minutes = minutes % 60 

是的,返回多个值(即一个元组)肯定是pythonic。 正如其他人所指出的那样,Python标准库以及备受推崇的Python项目中都有很多示例。 另外两个意见:

  1. 返回多个值有时非常有用。 举个例子,一个可select处理事件的方法(返回一些值),并返回成功或失败。 这可能出现在一个责任链的模式。 在其他情况下,您想要返回多个紧密链接的数据块,如示例中所示。 在这个设置中,返回多个值类似于用多个成员variables返回一个匿名类的单个实例。
  2. Python对方法参数的处理需要直接返回多个值的能力。 例如,在C ++中,方法参数可以通过引用传递,所以除了正式的返回值以外,还可以为它们分配输出值。 在Python中,参数是“通过引用”传递的(但是在Java,而不是C ++中)。 您不能将新值分配给方法参数,并将其反映在方法范围之外。 例如:

     // C++ void test(int& arg) { arg = 1; } int foo = 0; test(foo); // foo is now 1! 

    与之比较:

     # Python def test(arg): arg = 1 foo = 0 test(foo) # foo is still 0 

这绝对是pythonic。 事实上,你可以从一个函数返回多个值的样板,你会用像C这样的语言,在那里你需要定义一个结构为你返回的每个types的结构。

然而,如果你到了一个单一函数返回一些像10个值一样疯狂的地步,你应该认真考虑将它们捆绑在一个类中,因为在那个时候它变得笨拙。

返回一个元组很酷。 还要注意在python 2.6中添加的新的namedtuple,这可能会使得这个更适合你: http : //docs.python.org/dev/library/collections.html#collections.namedtuple

我相当新的Python,但元组技术似乎pythonic对我来说。 不过,我有另一个可能增强可读性的想法。 使用字典允许通过名称而不是位置访问不同的值。 例如:

 def divide(x, y): return {'quotient': x/y, 'remainder':x%y } answer = divide(22, 7) print answer['quotient'] print answer['remainder'] 

OT:RSRE的Algol68有好奇的“/:=”操作符。 例如。

 INT quotient:=355, remainder; remainder := (quotient /:= 113); 

商数为3,余数为16。

注意:通常,“(x /:= y)”的值被丢弃,因为商数“x”是由引用赋值的,但在RSRE的情况下,返回的值是余数。

cf 整型算术 – Algol68

使用一个元组来返回多个值,例如divmod这样简单的函数就divmod 。 如果它使代码可读,则是Pythonic。

如果返回值开始变得混乱,请检查函数是否做得太多,如果是的话就分割。 如果一个大元组像一个对象一样被使用,那么把它作为一个对象。 另外,请考虑使用命名元组 ,这些元组将成为Python 2.6标准库的一部分。