[英]What is the equivalent of java's 'constructor-overload' in python?
I'm currently studying Python.我目前正在学习 Python。 I was trying to write an exercise code making a 'Line'-class with different possible input-parameters and hence different constructors, as one can do in java.
我试图编写一个练习代码,使用不同的可能输入参数和不同的构造函数制作一个“Line”类,就像在 java 中所做的那样。 ie a constructor with (point,point) objects and a constructor with (point,slope) It works with both
__init__
methods separately, but not with both as it does in python.即具有 (point,point) 对象的构造函数和具有 (point,slope) 的构造函数它分别与
__init__
方法一起使用,但不像在 python 中那样同时使用。 Could anybody help me going with this.谁能帮我解决这个问题。
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())
You can use *kwargs
in __init__
method to check what arguments you received and act accordingly.您可以在
__init__
方法中使用*kwargs
来检查您收到的参数并相应地采取行动。 Your code modified should look like this.修改后的代码应如下所示。
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())
In Python, it's customary to write __init__
as the low-level initializer, which can also double as the primary "constructor".在 Python 中,习惯
__init__
编写为低级初始化程序,它也可以兼作主要的“构造函数”。 Additional constructors are defined as class methods.额外的构造函数被定义为类方法。
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)
# ...
Now Line
has two constructors:现在
Line
有两个构造函数:
Line.__new__
takes two Point
objects. Line.__new__
需要两个Point
对象。 (It's rare to actually override __new__
; the default of calling the parent's __new__
and using __init__
on the result is nearly always sufficient.) (实际上很少覆盖
__new__
;调用父对象的__new__
并在结果上使用__init__
的默认值几乎总是足够的。)
Line.from_point_slope
takes a Point
object and a slope. Line.from_point_slope
接受一个Point
对象和一个斜率。 It calculates a second point on the line from the first Point
and the slope, then pass them to Line.__new__
to create the new Line
.它从第一个
Point
和斜率计算线上的第二个点,然后将它们传递给Line.__new__
以创建新Line
。
Both constructors use Line.__init__
to actually set the two attributes p1
and p2
.两个构造函数都使用
Line.__init__
来实际设置两个属性p1
和p2
。
In the future, if you think of more ways to define a line (for example, as the intersection of two planes), you simply define new class methods, rather than complicating __init__
further.以后,如果您想到更多定义线的方法(例如,作为两个平面的交点),您只需定义新的类方法,而不是进一步复杂化
__init__
。
IMHO there are two rather simple ways to allow more than one construction syntax in Python.恕我直言,有两种相当简单的方法可以在 Python 中允许不止一种构造语法。
Assuming that you are trying to mimic the following pair of constructors in Java:假设您正在尝试在 Java 中模拟以下一对构造函数:
class Line {
public Line(Point p1, Point p2) {
...
}
public Line(Point p1, float a) {
...
}
...
}
The parameter type test (for the simplest use cases):参数类型测试(对于最简单的用例):
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 ...
The parameter name test for more complex use cases:更复杂用例的参数名称测试:
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.