我目前正在学习Python。我试图编写一个练习代码,使“线”类具有不同的可能的输入参数,从而具有不同的构造函数,就像在Java中一样。即具有(点,点)对象的构造函数和具有(点,斜率)对象的构造函数它分别与__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())
答案 0 :(得分:1)
您可以在*kwargs
方法中使用__init__
来检查收到的参数并采取相应的措施。修改后的代码应如下所示。
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())
答案 1 :(得分:0)
在Python中,习惯将XmlDocument
编写为低级初始化程序,该初始化程序还可以兼作主要的“构造函数”。其他构造函数被定义为类方法。
__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
复杂化。
答案 2 :(得分:0)
恕我直言,有两种相当简单的方法允许在Python中使用多种构造语法。
假设您要模仿Java中的以下构造函数对:
webView = (WebView) view.findViewById(R.id.webView);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setSupportZoom(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setUseWideViewPort(true);
webView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return (event.getAction() == MotionEvent.ACTION_MOVE);
}
});
webView.setScrollContainer(false);
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
webViewProgressBar.setProgress(newProgress);
super.onProgressChanged(view, newProgress);
}
});
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
webViewProgressBar.setVisibility(View.VISIBLE);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
webViewProgressBar.setVisibility(View.GONE);
webView.setVisibility(View.VISIBLE);
}
});
参数类型测试(用于最简单的用例):
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
...