Is it pythonic for a function to return multiple values?
在Python中,可以让函数返回多个值。这里有一个人为的例子:
1 2 3 4 5 6 | def divide(x, y): quotient = x/y remainder = x % y return quotient, remainder (q, r) = divide(22, 7) |
这似乎很有用,但看起来它也可能被滥用("好吧..函数x已经计算出作为中间值所需要的东西。"让x返回该值)。
你应该什么时候画线和定义一个不同的方法?
绝对(例如您提供的示例)。
tuples是python中的头等公民有一个内建函数
1 | q, r = divmod(x, y) # ((x - x%y)/y, x%y) Invariant: div*y + mod == x |
还有其他例子:
1 2 3 4 5 6 | 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库引用参考:
Tuples may be constructed in a number of ways:
- Using a pair of parentheses to denote the empty tuple: ()
- Using a trailing comma for a singleton tuple: a, or (a,)
- Separating items with commas: a, b, c or (a, b, c)
- Using the tuple() built-in: tuple() or tuple(iterable)
功能应为单一目的服务
因此,它们应该返回单个对象。在您的例子中,这个对象是一个元组。将元组视为特殊的复合数据结构。有些语言几乎每个函数都返回多个值(lisp中的列表)。
有时返回
在Python2.6中引入命名元组后,在许多情况下,最好返回命名元组,而不是纯元组。
1 2 3 4 5 6 7 8 9 10 11 12 13 | >>> 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)) >>> p.x, p.y, p[0], p[1] (0, 1, 0, 1) >>> for i in p: ... print(i) ... 0 1 |
首先,注意python允许以下内容(不需要括号):
1 | q, r = divide(22, 7) |
关于你的问题,没有硬性和快速的规则。对于简单的(通常是人为的)例子,似乎给定函数总是可能有一个单一的用途,从而产生一个单一的值。但是,在将Python用于实际应用程序时,您很快就会遇到许多情况,其中需要返回多个值,从而导致代码更干净。
所以,我想说,做任何有意义的事情,不要试图遵守一个人为的约定。python支持多个返回值,因此在适当的时候使用它。
您给出的示例实际上是一个名为
对我来说,如果代码更干净,那就是Python。比较这两个代码块:
1 2 3 4 5 6 7 8 9 | 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 |
是的,返回多重价值(i.e.,a tuple)是定义的Python。由于其他人已经指明,在Python标准图书馆以及在适当的Python项目中都有许多例子。另外两个评论:
Python's handling of method determinates necessitates the ability to directly return multiple values.例如,在C++中,方法参数可以通过引用来传输,因此,可以将输出值分配给他们,再加上形式回报值。In Python,are passed"by reference"(but in the sense of Java,not C+).你不能为方法论据分配新的价值,它反射出方法范围。For example:
1 2 3 4 5 6 7 8 | // C++ void test(int& arg) { arg = 1; } int foo = 0; test(foo); // foo is now 1! |
比较:
ZZU1
OT:RSRE's algol68 has the curious"/EG
1 2 | INT quotient:=355, remainder; remainder := (quotient /:= 113); |
给出一个商数,3,16。
注:Typically the value of(X/:=Y)"is discarded as quote"X"is assigned by reference,but in RSRE's case the returned value is the remainder.
C.F.Integer算法-算法68
返回元组很酷。还要注意新的名称在python 2.6中添加了这个选项,这可能会使您更喜欢它:http://docs.python.org/dev/library/collections.html collections.namedtuple
当然是Python。事实上,您可以从一个函数返回多个值,这个函数是您在C语言中使用的样板文件,在C语言中,您需要为在某个地方返回的每个类型组合定义一个结构。
但是,如果您达到了从一个函数返回疯狂值(比如10个值)的程度,那么您应该认真考虑将它们捆绑在一个类中,因为在这一点上,它会变得很难处理。
我是新来的Python,但水管技术看起来像是我的Python。但是,我有另一个想法,也许可以提高可行性。使用一个字典允许存取到不同值的名称比位置。For example:
1 2 3 4 5 6 | def divide(x, y): return {'quotient': x/y, 'remainder':x%y } answer = divide(22, 7) print answer['quotient'] print answer['remainder'] |
对于诸如
如果返回值开始变得混乱,请检查函数是否做得太多,如果做得太多,则将其拆分。如果一个大元组被当作一个对象来使用,就把它变成一个对象。另外,考虑使用命名的元组,它将是Python2.6中标准库的一部分。