python - 在 python 中实现多个构造函数的最佳实践

标签 python math line

我很确定这个问题已经被问过很多次了,但我仍然不确定如何在 Python 中实现多个构造函数。我知道在 python 中,我只能有一个构造函数,这与在 java 或 C# 或 C++ 中不同。我对它还是很陌生。长话短说,我需要实现一个线对象。该线将由函数 y = ax + b 表示。因此,我唯一需要存储在行中的是 a、b 和一个 bool 值,用于行是垂直的特殊情况(a = 无穷大)。在这种情况下,a 将存储该行的 x 位置。要创建一条线,我有 3 种方法。 1是直接把a,b和boolean放进去。 2是以元组的形式放入2个点。 3是放入一个点和一个向量。到目前为止我的代码:

class line:
    def __init__(self, a, b, noSlope):
        self.a = a
        self.b = b
        self.noSlope = noSlope

    def lineFromPoints(point1, point2):
        deltaX = point2[0] - point1[0]
        deltaY = point2[1] - point1[1]
        if deltaX == 0:
            return line(point1[0], 0, True)
        else:
            a = deltaY / deltaX
            b = point1[1] - a * point1[0]
            return line(a, b, False)

    def lineFromVector(vector, point):
        if vector[0] == 0:
            return line(point1[0], 0, True)
        else:
            a = vector[1] / vector[0]
            b = point1[1] - a * point1[0]
            return line(a, b, False)

不确定是否有更好的方法来做到这一点

最佳答案

更新:

使用 @classmethod 执行多个构造函数的更 pythonic 方式, 正如 Jim 所建议的那样. Raymond Hettinger 在 Pycon 2013 上做了一个关于 Python 类开发工具包的演讲,他谈到了 multiple constructors使用 @classmethod

class Line:
    def __init__(self, a, b, noSlope):
        self.a = a
        self.b = b
        self.noSlope = noSlope

    @classmethod
    def fromPoints(cls, point1, point2):
        deltaX = point2[0] - point1[0]
        deltaY = point2[1] - point1[1]
        if deltaX == 0:
            return cls(point1[0], 0, True)
        else:
            a = deltaY / deltaX
            b = point1[1] - a * point1[0]
            return cls(a, b, False)

    @classmethod
    def fromVector(cls, vector, point):
        if vector[0] == 0:
            return cls(point1[0], 0, True)
        else:
            a = vector[1] / vector[0]
            b = point1[1] - a * point1[0]
            return cls(a, b, False)


line = Line.fromPoints((0,0), (1,1))

类似于self@classmethod 函数的cls 参数作为调用类隐式传递(在上面的示例中,它将是 Line)。这用于使用额外的构造函数来容纳 future 的子类;它通过硬编码基类代替 cls 来消除意外绕过子类的构造函数实现的潜在错误。


原帖:

如果你想强制使用你的构造函数,你可以将它们设为 static methods ,并让他们返回您的类的一个实例。

class line:
    def __init__(self, a, b, noSlope):
        self.a = a
        self.b = b
        self.noSlope = noSlope

    @staticmethod
    def lineFromPoints(point1, point2):
        deltaX = point2[0] - point1[0]
        deltaY = point2[1] - point1[1]
        if deltaX == 0:
            return line(point1[0], 0, True)
        else:
            a = deltaY / deltaX
            b = point1[1] - a * point1[0]
            return line(a, b, False)

    @staticmethod
    def lineFromVector(vector, point):
        if vector[0] == 0:
            return line(point1[0], 0, True)
        else:
            a = vector[1] / vector[0]
            b = point1[1] - a * point1[0]
            return line(a, b, False)

# Create instance of class
myLine = line.lineFromPoints((0,0), (1,1))

编辑:
如果您想强制使用您的构造函数而不是使用 Line.__init__,您可以使用以下工厂来隐藏 Line 类的直接实例化:

class LineFactory:
    class Line:
        def __init__(self, a, b, noSlope):
            self.a = a
            self.b = b
            self.noSlope = noSlope

    @staticmethod
    def fromPoints(point1, point2):
        deltaX = point2[0] - point1[0]
        deltaY = point2[1] - point1[1]
        if deltaX == 0:
            return LineFactory.Line(point1[0], 0, True)
        else:
            a = deltaY / deltaX
            b = point1[1] - a * point1[0]
            return LineFactory.Line(a, b, False)

    @staticmethod
    def fromVector(vector, point):
        if vector[0] == 0:
            return LineFactory.Line(point1[0], 0, True)
        else:
            a = vector[1] / vector[0]
            b = point1[1] - a * point1[0]
            return LineFactory.Line(a, b, False)

# Create line    
line = LineFactory.fromPoints((0,0), (1,1))

关于python - 在 python 中实现多个构造函数的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36251814/

相关文章:

python - 在 tkinter 中更改框架的大小,由类定义

c - 我的字符、单词、行数计数程序有什么问题?

python - 语法错误: invalid syntax href = 'http://maps.google.com' + href

python - 如何去除图像中对象的边缘噪声

javascript - 如何检测与曲线的碰撞

math - float 学有问题吗?

c - 整数除法的行为是什么?

javascript - 为什么我的折线图过渡看起来滞后?

PHP explode 在一行中获取特定的索引值

python - statsmodels 中的指数平滑给出错误