Returning an object vs returning a tuple

Returning an object vs returning a tuple

不再见 发布于 2021-11-30 字数 2677 浏览 799 回复 7 原文

I am developing in python a file class that can read and write a file, containing a list of xyz coordinates. In my program, I already have a Coord3D class to hold xyz coordinates.

My question is relative to the design of a getCoordinate(index) method. Should I return a tuple of floats, or a Coord3D object?

In the first case, I get very low coupling, but then I will probably have to instantiate a Coord3D object with the obtained values anyway, although outside of the file class. In the second case, I will have the file class tightly coupled with the Coord3D class.

Please note that I think there's not a huge difference between the two solutions, but I would like to read your answer and the reason behind it.


Edit: to recap the answers I got until now, it looks like there's no clearcut choice. It has been said (appropriately) that python is not Java, and you don't need a specialized class for everything just because you need it by language architecture. In my case, however, I have the following conditions:

  1. I am working on a library, where the Coord3D object is used as is. Using it would increase the cohesiveness of my library, as the data types will be uniformly used.
  2. The Coord3D object has state and behavior. Indeed, the Coord3D object aggregate the coordinates and the units in a single entity. Operations among Coord3D objects will keep into account the potentially different units, and act accordingly.
  3. I can put centralize control code into the Coord3D class instantiation to refuse, for example, arrays of length 4, or non units. If I use a tuple, I cannot perform this check. Moreover, if a method accepts a Coord3D, is sort of guaranteed that it's well formed upfront (you could be bold and check for isinstance, or check the interface). A tuple can contain invalid data. Although python approach to error handling is done where the trouble happen, a class preventing me to have an xyz coordinate made out of three strings is somehow beneficial (correct me if wrong, please)

On the other hand, using a tuple has the following advantages:

  1. Less occupation of resources, quite critical in case of huge
  2. Simpler design. More classes means more complex design. A tuple is a standard data type which is well understood and can be unpacked easily. A personalized class is not.
  3. Using a tuple, the XYZFile class is totally decoupled from the rest of the library (because it does not use the Coord3D object). This means that it can be reused totally as an independent entity.

further comments very welcome!

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

千里故人稀 2022-06-07 7 楼

Returning an object would be the best practice and would give you a better overall software design. I would recommend doing that

But still, keep in mind that creating/returning an object will take more processing time. It could change something if you do this operation a LOT and in that case you might need to think about it...

∞觅青森が 2022-06-07 6 楼

If it's only going to be used in your application, and if you're going to create a Coord3D instance with the values anyway, I'd just return a Coord3D instance to save you the effort. If, however, you have any interest in making this portable/general, return a tuple. It'll be easy to create a Coord3D anyway, using

c3d = Coord3D(*getCoordinate(index))

(assuming your constructor is Coord3D.__init__(self, x, y, z))

物价感观 2022-06-07 5 楼

I've asked myself the same question, albeit while doing 2D geometry stuff.

The answer I found for myself was that if I was planning to write a larger library, with more functions and whatnot, go ahead and return the Point, or in your case the Coord3D object. If it's just a hacky implementation, the tuple will get you going faster. In the end, it's just what you're going to do with it, and is it worth the effort.

我很OK 2022-06-07 4 楼

Take a look at Will McGugan's Gameobjects library. He has a Vector3 class that can be initialized with another Vector3 object, a tuple, individual float values, etc. I think this will answer your question ... plus you may end up just using his library as it's already optimized and has plenty of useful methods already.

不如归去 2022-06-07 3 楼

The more fundamental question is "why do you have Coord3D class?" Why not just use a tuple?

The general advice most of us give to Python n00bz is "don't invent new classes until you have to."

Does your Coord3D have unique methods? Perhaps you need a new class. Or -- perhaps -- you only need some functions that operate on tuples.

Does your Coord3D have changeable state? Hardly likely. An immutable tuple starts to look like a better representation than a new class.

我还不会笑 2022-06-07 2 楼

If other people (aside form yourself) will be using this class, it seems to me that returning an object would encourage some kind of uniformity in data types. If the Coord3D class has a method or property to access these coordinates as a tuple, then that still gives them that option, should they need it:

# 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
夏末染殇 2022-06-07 1 楼

Compromise solution: Instead of a class, make Coord3D a namedtuple and return that :-)

Usage:

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

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

The return value can be used exactly as a tuple, and has the same speed and memory properties, so you don't lose any genericity. But you can also access its values by name: if c is the result of getCoordinate(index), then you can work with c.x, c.y, etc, for increased readibility.

(obviously this is a bit less useful if your Coord3D class needs other functionality too)

[if you're not on python2.6, you can get namedtuples from the cookbook recipe]