返回一个对象与返回一个元组

时间:2009-04-27 15:48:49

标签: python

我在python中开发了一个文件类,可以读取和写入一个包含xyz坐标列表的文件。在我的程序中,我已经有一个Coord3D类来保存xyz坐标。

我的问题与getCoordinate(index)方法的设计有关。我应该返回一个浮点元组还是一个Coord3D对象?

在第一种情况下,我的耦合非常低,但是我可能不得不用获得的值实例化一个Coord3D对象,尽管在文件类之外。在第二种情况下,我将把文件类与Coord3D类紧密结合。

请注意,我认为两种解决方案之间没有太大差异,但我想了解你的答案及其背后的原因。


编辑:回顾一下到现在为止的答案,看起来没有明确的选择。有人说(适当地)python不是Java,并且你不需要专门的类来处理所有事情,因为你需要语言架构。但就我而言,我有以下条件:

  1. 我正在使用一个库,其中Coord3D对象按原样使用。使用它会增加我的库的内聚性,因为数据类型将被统一使用。
  2. Coord3D对象具有状态和行为。实际上,Coord3D对象聚合单个实体中的坐标和单位。 Coord3D对象之间的操作将考虑可能不同的单位,并采取相应的行动。
  3. 我可以将集中控制代码放入Coord3D类实例中以拒绝,例如,长度为4或非单位的数组。如果我使用元组,我无法执行此检查。此外,如果一个方法接受Coord3D,有点保证它是预先形成的(你可以加粗并检查isinstance,或检查界面)。元组可以包含无效数据。虽然python处理错误的方法是在发生故障的地方完成的,但是一个阻止我用三个字符串组成的xyz坐标的类在某种程度上是有益的(请纠正我,如果有错误的话)
  4. 另一方面,使用元组具有以下优点:

    1. 少占用资源,在巨大的情况下非常关键
    2. 设计简单。更多类意味着更复杂的设计。元组是一种标准数据类型,很容易理解,可以轻松解压缩。个性化课程不是。
    3. 使用元组,XYZFile类与库的其余部分完全分离(因为它不使用Coord3D对象)。这意味着它可以作为一个独立的实体完全重用。
    4. 进一步的评论非常欢迎!

7 个答案:

答案 0 :(得分:13)

妥协解决方案:将Coord3D改为namedtuple而不是类,并返回: - )

用法:

Coord3D = namedtuple('Coord3D', 'x y z')

def getCoordinate(index):
    # do stuff, creating variables x, y, z
    return Coord3D(x, y, z)

返回值可以完全用作元组,并且具有相同的速度和内存属性,因此您不会失去任何通用性。但您也可以按名称访问其值:如果c是[{1}}的结果,那么您可以使用getCoordinate(index)c.x等,以提高可读性。< / p>

(显然,如果您的Coord3D类还需要其他功能,这样做有点不太有用)

[如果你不在python2.6上,你可以从cookbook recipe]获得命名元组

答案 1 :(得分:2)

如果其他人(除了形成你自己)将使用这个类,在我看来,返回一个对象会鼓励数据类型的某种统一性。如果Coord3D类有一个方法或属性来访问这些坐标作为元组,那么如果他们需要它仍然给他们这个选项:

# get the object
coord_obj = my_obj.getCoordinate(my_index)
# get the tuple (for example, via a property named "coords")
coord_tup = my_obj.getCoordinate(my_index).coords

答案 2 :(得分:2)

更基本的问题是“为什么你有Coord3D课程?”为什么不使用元组?

我们大多数人给Python n00bz的一般建议是“除非必须,否则不要发明新课程。”

你的Coord3D有独特的方法吗?也许你需要一个新的课程。或者 - 也许 - 你只需要一些对元组进行操作的函数。

您的Coord3D是否具有可变状态?很可能。不可变元组开始看起来比新类更好。

答案 3 :(得分:2)

看看Will McGugan的Gameobjects library。他有一个Vector3 class,可以使用另一个Vector3对象,一个元组,单个浮点值等进行初始化。我认为这将回答你的问题...加上你可能最终只使用他的库,因为它已经被优化了已经有很多有用的方法。

答案 4 :(得分:1)

如果它只在您的应用程序中使用,并且如果您要创建一个带有值的Coord3D实例,我只需返回Coord3D实例以节省您的努力。但是,如果您对制作便携式/普通型有兴趣,请返回元组。无论如何,使用

创建Coord3D会很容易
c3d = Coord3D(*getCoordinate(index))

(假设你的构造函数是Coord3D.__init__(self, x, y, z)

答案 5 :(得分:1)

我问自己同样的问题,虽然在做2D几何体时。

我自己找到的答案是,如果我打算编写一个更大的库,有更多的函数和诸如此类的东西,请继续返回Point,或者在你的情况下返回Coord3D对象。如果它只是一个hacky实现,元组将让你更快。最后,这就是你要做的事情,值得努力。

答案 6 :(得分:1)

返回对象将是最佳实践,并为您提供更好的整体软件设计。我建议那样做

但是,请记住,创建/返回对象将需要更多的处理时间。如果您执行此操作可能会改变一些情况,在这种情况下您可能需要考虑它......