I'm currently playing around with 2D geometry. I created two classes: Point
and LineSegment
:
class Point:
def __init__(self, x: float, y: float):
self.x = x
self.y = y
class LineSegment:
def __init__(self, p1: Point, p2: Point):
self.p1 = p1
self.p2 = p2
An interesting case is LineSegment(p1, p1)
- hence a line segment of length zero. Essentially, this is just the point p1
. But it is of type LineSegment
.
I will likely use something like the following to deal with that case:
class LineSegment:
def __init__(self, p1: Point, p2: Point):
self.p1 = p1
self.p2 = p2
def simplify(self):
if self.p1 == self.p2:
return self.p1
return self
Although it is likely a very bad idea, I'm still curious: Is it possible to make the constructor of class LineSegment
return an object of class Point
?
Yes, using __new__()
.
class LineSegment:
def __new__(cls, p1: Point, p2: Point):
# Using "is" here since Points are mutable, but that's just personal preference
if p1 is p2:
return p1
return super().__new__(cls)
def __init__(self, p1: Point, p2: Point):
self.p1 = p1
self.p2 = p2
a = Point(0, 0)
b = Point(1, 1)
print(LineSegment(a, b)) # <__main__.LineSegment object at ...>
print(LineSegment(a, a)) # <__main__.Point object at ...>
Note, from the docs
If
__new__()
does not return an instance of cls, then the new instance’s__init__()
method will not be invoked.