繁体   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