[英]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.