Is the concept of a Point3 class, separate from a Vec3 class, unpythonic?
I'm writing some 3D math classes for Python. I'd like to make a Point3 class that is separate from Vec3 in the following respects:
Point3 - Point3 = Vec3
Point3 + Vec3 = Point3
Otherwise, all operations on Vec3 you can perform on Point3. The motivation for this is to separate the mathematical concept of a point from a vector, hopefully leading to clearer type separation and an easier to understand API.
However, with Python's duck typing and the common practice of expecting a certain interface regardless of type, is it better just开发者_StackOverflow社区 to use a Vec3? Is it more efficient?
It seems superfluous. If you think about it, a point in cartesian space is entirely equivalent to a bound vector which begins at the origin. Sounds like you could be making a lot of work for yourself for nothing.
I don't think this is particularly unpythonic. It's not too unusual to distinguish types when they have the same domain, but when one has a particular frame of reference, such as a time zone, Since a point is the sum of a vector and the origin, it's reasonable to encode that in some way.
I understand your argument. I, too, have always struggled with classes for points. In my experience it's better (although I guess perhaps not "more pythonic") to take a more functional approach and write your API in terms of functions that takes lists/tuples.
The main objection to this, I think, is that you probably want a compact way of writing simple algebraic operations (sums etc.), but for that I would suggest using numpy. Not only does numpy support element-wise addition, but it gives you efficiency where you are likely to need it in the future, with matrix operations and the like.
At the same time, while you say that you want a clean API, the differences you are adding to the API will be invisible, except in the documentation. And really, an invisible API is not that useful.
I know this is nothing like what you were originally asking, but I suspect it is the best design in the long term (i.e. as your library grows and you want to support more ambitious transformations of points, batch processing, etc., etc.).
Yes, this is poor design, as adding or subtracting two points has no conceptual meaning.
You can, however, add a vector to a point (obtaining a point) or add two vectors (obtaining a vector), so it sounds like you are just confusing points with vectors.
A point is not a vector, but it can be implemented in terms of one. In programming, we model "implemented-in-terms-of" relationships using composition - the Point
class will contain a single private Vector
instance, and use it to handle the logic of whatever methods it exposes.
In fact, because a Vector
can already do all the same things a Point
can (plus more), you may want to consider not even bothering to make the distinction, and using only the Vector
class, with no Point
class at all. Whether or not this is a good idea depends on what your API will be used for.
精彩评论