返回对象与返回元组
我正在用Python开发一个文件类,这个类可以读取和写入一个包含xyz坐标的文件。在我的程序中,我已经有了一个Coord3D类,用来存储xyz坐标。
我想问的是,设计一个getCoordinate(index)方法时,应该返回一个浮点数的元组,还是返回一个Coord3D对象呢?
如果我选择返回元组,这样的耦合度很低,但我可能还是得用这些值来创建一个Coord3D对象,只不过是在文件类之外。如果我选择返回Coord3D对象,那么文件类和Coord3D类的关系就会很紧密。
我觉得这两种方案之间没有太大的区别,但我想看看你们的看法和理由。
编辑:总结一下我到目前为止得到的回答,似乎没有明确的选择。有些人提到(说得很对)Python和Java不一样,你不需要因为语言架构的原因就为每个东西都创建一个专门的类。不过在我的情况下,我有以下几点考虑:
- 我在开发一个库,Coord3D对象会直接使用。这样做会提高我库的内聚性,因为数据类型会统一使用。
- Coord3D对象有状态和行为。实际上,Coord3D对象把坐标和单位聚合成一个整体。在Coord3D对象之间的操作会考虑到可能不同的单位,并相应地进行处理。
- 我可以把控制代码集中在Coord3D类的实例化中,拒绝例如长度为4的数组或没有单位的情况。如果我使用元组,就无法进行这样的检查。而且,如果一个方法接受Coord3D对象,就可以保证它是正确的(你可以大胆地检查类型,或者检查接口)。元组可能包含无效数据。虽然Python处理错误的方式是在出错的地方处理,但一个类可以防止我用三个字符串构成一个xyz坐标,这样是有好处的(如果我说错了请纠正我)。
另一方面,使用元组有以下优点:
- 占用资源更少,这在处理大量数据时非常关键。
- 设计更简单。类越多,设计就越复杂。元组是一个标准数据类型,大家都很理解,而且可以很容易地拆解。自定义类就不一定了。
- 使用元组的话,XYZFile类和库的其他部分完全解耦(因为它不使用Coord3D对象)。这意味着它可以作为一个独立的实体被完全重用。
欢迎进一步的评论!
7 个回答
如果除了你自己,还有其他人会使用这个类,那么我觉得返回一个对象会让数据类型更加统一。如果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
折中方案:与其使用一个类,不如把Coord3D做成一个namedtuple
,然后返回这个东西 :-)
使用方法:
Coord3D = namedtuple('Coord3D', 'x y z')
def getCoordinate(index):
# do stuff, creating variables x, y, z
return Coord3D(x, y, z)
返回的值可以像元组一样使用,速度和内存占用也一样,所以你不会失去任何通用性。不过,你还可以通过名字来访问它的值:如果c
是getCoordinate(index)
的结果,那么你可以用c.x
、c.y
等来提高可读性。
(显然,如果你的Coord3D类还需要其他功能,这样做就没那么有用了)
[如果你不是在使用python2.6,可以从食谱中获取namedtuples]
我也曾经问过自己同样的问题,不过当时是在做2D几何相关的事情。
我找到的答案是,如果你打算写一个比较大的库,里面有更多的功能和其他东西,那就可以直接返回Point,或者在你的情况下返回Coord3D对象。如果只是简单的实现,使用元组会让你更快上手。最终,这一切都取决于你打算怎么用它,以及这是否值得你花费精力去做。