Python中一个类的构造函数可以返回另一个类吗?

Mar*_*oma 5 python oop

我目前正在研究二维几何。我创建了两个类:PointLineSegment

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
Run Code Online (Sandbox Code Playgroud)

一个有趣的情况是LineSegment(p1, p1)- 因此长度为零的线段。本质上,这就是重点p1。但它是类型LineSegment

我可能会使用类似以下的方法来处理这种情况:

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
Run Code Online (Sandbox Code Playgroud)

尽管这可能是一个非常糟糕的主意,但我仍然很好奇:是否可以使类的构造函数LineSegment返回类的对象Point

wja*_*rea 5

是的,虽然不是构造函数__init__(),而是实例化器__new__()

\n\n
class LineSegment:\n    def __new__(cls, p1: Point, p2: Point):\n        # Using "is" here since Points are mutable, but that\'s just personal preference\n        if p1 is p2:\n            return p1\n        return super().__new__(cls)\n\n    def __init__(self, p1: Point, p2: Point):\n        self.p1 = p1\n        self.p2 = p2\n\na = Point(0, 0)\nb = Point(1, 1)\nprint(LineSegment(a, b))  # <__main__.LineSegment object at ...>\nprint(LineSegment(a, a))  # <__main__.Point object at ...>\n
Run Code Online (Sandbox Code Playgroud)\n\n

注意,来自文档

\n\n
\n

如果不返回cls__new__()的实例,则不会调用new instance\xe2\x80\x99s方法。__init__()

\n
\n

  • `p1 is p2` 并不理想,因为简化对于 `LineSegment(Point(0,0), Point(0,0))` 不起作用 (2认同)
  • 嗯,简并线段就是一个点,无论每个参数中的点是否由同一个 Python 对象表示。我想我的立场是:返回与 __new__ 不同类型的对象没有问题,只要这样做有意义。在什么情况下它才有意义是一个完全不同的问题。 (2认同)
  • 我想在这种情况下我会选择“==”,因为没有任何理由区分代表同一点的两个“Point”对象。 (2认同)