簡體   English   中英

python中java的'constructor-overload'的等價物是什么?

[英]What is the equivalent of java's 'constructor-overload' in python?

我目前正在學習 Python。 我試圖編寫一個練習代碼,使用不同的可能輸入參數和不同的構造函數制作一個“Line”類,就像在 java 中所做的那樣。 即具有 (point,point) 對象的構造函數和具有 (point,slope) 的構造函數它分別與__init__方法一起使用,但不像在 python 中那樣同時使用。 誰能幫我解決這個問題。

class Point:
    def __init__(self,x,y):
        self.x=x
        self.y=y
    def distance_to(self,p):
        return((p1.x-p.x)**2+(p1.y-p.y)**2)**(1/2)

class Line:
    def __init__(self, p1,p2):
        self.p1=p1
        self.p2=p2
    def __init__(self,p1,a):
        self.p1=p1
        self.a=a
        b=self.p1.y-a*p1.x
        p2=Point(0,b)
        self.p2=p2             
    def slope(self):
        return (p2.y-p1.y)/(p2.x-p1.x)
    def b_intersect(self):
        b_intersect=self.p1.y-self.slope()*p1.x
    def __str__(self):       
        b_intersect=self.p1.y-self.slope()*p1.x               
        if b_intersect>0:
            return 'y={}x+{}'.format(self.slope(),b_intersect)
        elif b_intersect<0:
            return 'y={}x{}'.format(self.slope(),b_intersect)
        elif b_intersect==0:
            return 'y={}x'.format(self.slope())

您可以在__init__方法中使用*kwargs來檢查您收到的參數並相應地采取行動。 修改后的代碼應如下所示。

class Point:
    def __init__(self,x,y):
        self.x=x
        self.y=y
    def distance_to(self,p):
        return((p1.x-p.x)**2+(p1.y-p.y)**2)**(1/2)

class Line:
    def __init__(self, p1,**kwargs):
        self.p1=p1
        if kwargs.get("p2") is not None:
            self.p2=p2
        elif kwargs.get("a")is not None:
            self.a=a
            b=self.p1.y-a*p1.x
            p2=Point(0,b)
            self.p2=p2  
        else:
           raise Exception("Did not give enough parameters")           
    def slope(self):
        return (p2.y-p1.y)/(p2.x-p1.x)
    def b_intersect(self):
        b_intersect=self.p1.y-self.slope()*p1.x
    def __str__(self):       
        b_intersect=self.p1.y-self.slope()*p1.x               
        if b_intersect>0:
            return 'y={}x+{}'.format(self.slope(),b_intersect)
        elif b_intersect<0:
            return 'y={}x{}'.format(self.slope(),b_intersect)
        elif b_intersect==0:
            return 'y={}x'.format(self.slope())

在 Python 中,習慣__init__編寫為低級初始化程序,它也可以兼作主要的“構造函數”。 額外的構造函數被定義為類方法。

class Line:
    def __init__(self, p1, p2):
        self.p1 = p1
        self.p2 = p2

    @classmethod
    def from_point_slope(cls, p1, a):
        b = self.p1.y - a * p1.x
        p2 = Point(0, b)
        return cls(p1, p2)

   # ...

現在Line有兩個構造函數:

  1. Line.__new__需要兩個Point對象。 (實際上很少覆蓋__new__ ;調用父對象的__new__並在結果上使用__init__的默認值幾乎總是足夠的。)

  2. Line.from_point_slope接受一個Point對象和一個斜率。 它從第一個Point和斜率計算線上的第二個點,然后將它們傳遞給Line.__new__以創建新Line

兩個構造函數都使用Line.__init__來實際設置兩個屬性p1p2

以后,如果您想到更多定義線的方法(例如,作為兩個平面的交點),您只需定義新的類方法,而不是進一步復雜化__init__

恕我直言,有兩種相當簡單的方法可以在 Python 中允許不止一種構造語法。

假設您正在嘗試在 Java 中模擬以下一對構造函數:

class Line {
    public Line(Point p1, Point p2) {
        ...
    }
    public Line(Point p1, float a) {
        ...
    }
    ...
}
  1. 參數類型測試(對於最簡單的用例):

     class Line: def __init__(self, p1, p2): if isinstance(p2, Point): # ok, initialize the Line object from 2 points ... else: slope = p2 # ok, initialize the line object from 1 point and 1 float ...
  2. 更復雜用例的參數名稱測試:

     class Line: def __init__(self, p1, p2=None, slope=None): # test whether syntax is Ok (optional) if (p2 is None and slope is None) or (p2 is not None and slope is not None): raise ValueError("Either p2 or slope must be given") if slope is None: # ok, initialize the Line object from 2 points p1 and p2 ... else: # ok, initialize the line object from p1 and slope ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM