关闭。这个问题是opinion-based .它目前不接受答案。
想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题.
2年前关闭。
Improve this question
在支持它的语言中返回多个值的规范方法通常是 tupling .
选项:使用元组
考虑这个简单的例子:
def f(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return (y0, y1, y2)
但是,随着返回值数量的增加,这很快就会出现问题。如果你想返回四个或五个值怎么办?当然,你可以继续对它们进行元组化,但很容易忘记哪个值在哪里。在您想接收它们的任何地方打开它们也很丑陋。选项:使用字典
下一个合乎逻辑的步骤似乎是引入某种“记录符号”。在 Python 中,显而易见的方法是通过
dict
.考虑以下:
def g(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return {'y0': y0, 'y1': y1 ,'y2': y2}
(为了清楚起见,y0、y1 和 y2 只是作为抽象标识符的意思。正如所指出的,在实践中你会使用有意义的标识符。)现在,我们有了一种机制,我们可以转换出返回对象的特定成员。例如,
result['y0']
选项:使用类但是,还有另一种选择。我们可以改为返回一个专门的结构。我已经在 Python 的上下文中对此进行了框架化,但我确信它也适用于其他语言。事实上,如果您使用 C 语言,这很可能是您唯一的选择。开始:
class ReturnValue:
def __init__(self, y0, y1, y2):
self.y0 = y0
self.y1 = y1
self.y2 = y2
def g(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return ReturnValue(y0, y1, y2)
在 Python 中,前两者在管道方面可能非常相似 - 毕竟 { y0, y1, y2 }
只是最终成为内部 __dict__
中的条目的ReturnValue
.Python 还为微小对象提供了一项附加功能,即
__slots__
属性。该类可以表示为:class ReturnValue(object):
__slots__ = ["y0", "y1", "y2"]
def __init__(self, y0, y1, y2):
self.y0 = y0
self.y1 = y1
self.y2 = y2
来自 Python Reference Manual :The
__slots__
declaration takes a sequence of instance variables and reserves just enough space in each instance to hold a value for each variable. Space is saved because__dict__
is not created for each instance.
选项:使用 dataclass (Python 3.7+)
使用 Python 3.7 的新数据类,返回一个带有自动添加的特殊方法、类型和其他有用工具的类:
@dataclass
class Returnvalue:
y0: int
y1: float
y3: int
def total_cost(x):
y0 = x + 1
y1 = x * 3
y2 = y0 ** y3
return ReturnValue(y0, y1, y2)
选项:使用列表我忽略的另一个建议来自蜥蜴比尔:
def h(x):
result = [x + 1]
result.append(x * 3)
result.append(y0 ** y3)
return result
不过,这是我最不喜欢的方法。我想我已经被 Haskell 所感染,但是混合类型列表的想法一直让我感到不舒服。在这个特定的例子中,列表是 -not-mixed 类型,但可以想象它可能是。据我所知,以这种方式使用的列表实际上对元组没有任何好处。 Python 中列表和元组之间唯一真正的区别是列表是 mutable ,而元组不是。
我个人倾向于继承函数式编程的约定:对任意数量的相同类型的元素使用列表,对预定类型的固定数量的元素使用元组。
问题
在冗长的序言之后,是不可避免的问题。哪种方法(您认为)最好?
最佳答案
Named tuples为此目的在 2.6 中添加了。另见 os.stat对于类似的内置示例。
>>> import collections
>>> Point = collections.namedtuple('Point', ['x', 'y'])
>>> p = Point(1, y=2)
>>> p.x, p.y
1 2
>>> p[0], p[1]
1 2
在 Python 3 的最新版本(我认为是 3.6+)中,新的
typing
图书馆得到了 NamedTuple
类使命名元组更容易创建和更强大。继承自 typing.NamedTuple
允许您使用文档字符串、默认值和类型注释。示例(来自文档):
class Employee(NamedTuple): # inherit from typing.NamedTuple
name: str
id: int = 3 # default value
employee = Employee('Guido')
assert employee.id == 3
关于python - 从函数返回多个值的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/354883/