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

Jac*_* Le 1 python math line

我很确定已多次询问过这个问题,但我仍然不确定如何在Python中实现多个构造函数.我知道在python中,我只能有一个不同于java或C#或C++的构造函数.我还是很新的.长话短说,我需要实现一个线对象.该线将由函数y = ax + b表示.因此,我需要在行中存储的唯一内容是a,b和布尔值,用于特殊情况,其中行是垂直的(a =无穷大).在这种情况下,a将存储该行的x位置.要创建一条线,我有三种方法.1是直接放入a,b和布尔值.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)
Run Code Online (Sandbox Code Playgroud)

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

Ste*_*ith 7

更新:

@classmethod正如吉姆所建议的那样,做多个构造函数的pythonic方式就越多.Raymond Hettinger在2013年的Pycon上讨论了Python的类开发工具包,在那里他谈到了使用的多个构造函数@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))
Run Code Online (Sandbox Code Playgroud)

类似于self,函数的cls参数@classmethod隐式地作为调用类传递(在上面的例子中,它将是Line).这用于使用其他构造函数来适应未来的子类; 它通过硬编码基类来代替,从而意外地绕过子类的构造函数实现,从而消除了潜在的错误cls.


原始邮寄:

如果要强制使用构造函数,可以将它们设置为静态方法,并让它们返回类的实例.

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

编辑:
如果你想强制使用你的构造函数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))
Run Code Online (Sandbox Code Playgroud)