Skip to main content
 首页 » 编程设计

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

2025年05月04日16mate10pro

我很确定这个问题已经被问过很多次了,但我仍然不确定如何在 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))