[英]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
有兩個構造函數:
Line.__new__
需要兩個Point
對象。 (實際上很少覆蓋__new__
;調用父對象的__new__
並在結果上使用__init__
的默認值幾乎總是足夠的。)
Line.from_point_slope
接受一個Point
對象和一個斜率。 它從第一個Point
和斜率計算線上的第二個點,然后將它們傳遞給Line.__new__
以創建新Line
。
兩個構造函數都使用Line.__init__
來實際設置兩個屬性p1
和p2
。
以后,如果您想到更多定義線的方法(例如,作為兩個平面的交點),您只需定義新的類方法,而不是進一步復雜化__init__
。
恕我直言,有兩種相當簡單的方法可以在 Python 中允許不止一種構造語法。
假設您正在嘗試在 Java 中模擬以下一對構造函數:
class Line {
public Line(Point p1, Point p2) {
...
}
public Line(Point p1, float a) {
...
}
...
}
參數類型測試(對於最簡單的用例):
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 ...
更復雜用例的參數名稱測試:
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.