2016-03-27 84 views
1

我非常肯定這已經被問了很多次,但我仍然不確定如何在Python中實現多個構造函數。我知道在python中,我只能有一個不同於java或C#或C++的構造函數。我對它仍然很陌生。長話短說,我需要實現一個線對象。該行將由函數y = ax + b表示。所以我需要在行中存儲的唯一東西是a,b和布爾值,用於垂直線(a =無窮大)的特殊情況。在這種情況下,a將存儲該行的x位置。爲了創建一條線,我有3種方法。 1是直接放入a,b和布爾值。 2是以元組的形式放2分。 3是放在一個點和一個向量。到目前爲止我的代碼:在python中實現多個構造函數的最佳實踐

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) 

不知道是否有更好的方法來做到這一點

+0

由於這是一個Python問題,請刪除C#和C++代碼,因爲它無關,與你的問題 – BugFinder

+0

謝謝。我只是做了 –

+0

不知道你在問什麼具體問題,而且構造函數看起來很好,但是有一些非常突出的東西 - 類名總是大寫,所以稱之爲'class Line:'。對於所有這些索引查找('point1 [0]'等),你可以說'x1,y1 = point1'和'x2,y2 = point2',然後你的'deltaX'可以只是'x2-x1'後來你可以重複使用'x1,x2,y1,y2'等。基本上把你的符號想象成如果我試圖在紙上解決一些相似的數學方程,我該如何做到這一點。 – Bahrom

回答

5

UPDATE:

做多個構造的更多Python的方式是@classmethod,由Jim的建議。 Raymond Hettinger在Pycon 2013上就Python的班級開發工具包進行了演講,在那裏他使用@classmethod談論了multiple constructors

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類似,cls參數爲@classmethod用作調用類隱式傳遞(在上面的例子中,這將是Line)。這用於使用其他構造函數來適應未來的子類;它通過硬編碼基類來代替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__,您可以使用下面的工廠隱藏線類直接實例:

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)) 
+0

我正要編輯我的評論並提出靜態方法,這是一個很好的方法。你也可以大寫類名(只是一個建議) – Bahrom

+0

我建議大寫這個名字! – sdsmith

+0

問題:現在是否仍然可以使用Line類,因爲它被包含在LineFactory類中? –

0

您可以創建一個構造函數所需的所有參數的默認值無:

class line: 
    def __init__(self, a = None, b = None, noSlope = None, point1 = None, point2 = None, vector = None, point = None): 
     pass 

然後你會檢查哪些paameters在構造函數中傳遞並從這些參數創建行。

0

你可以使用Pyhton的枚舉來聲明初始化方法如下:

from enum import Enum 

class Line: 

    class InitTypes(Enum): 
     coefs, point_vector, point_point, vertical = range(4) 


    def __init__(self, a, b, method): 
     self.noSlope = False 
     if method == Line.InitTypes.coefs: 
      self.a = a 
      self.b = b 
     elif method == Line.InitTypes.point_vector: 
      # Do math 
      pass 
     elif method == Line.InitTypes.point_point: 
      # Do math 
      pass 
     elif method == Line.InitTypes.vertical: 
      self.noSlope = True 
      self.a = a 
      self.b = b 
     else: 
      assert(False) 

然後,創建一個如下所示的行:

x = Line((0,1), (3,4), Line.InitTypes.point_point) 
+0

這是一個有趣的方式來做到這一點。 hmmmm .. –