Python 使用 OOP 的圆的语言中心

Python language-center of a circle using OOP

class Point:

    def __init__(self, initX, initY):
        """ Create a new point at the given coordinates. """
        self.x = initX
        self.y = initY

    def getX(self):
        return self.x

    def getY(self):
        return self.y

    def distanceFromOrigin(self):
        return ((self.x ** 2) + (self.y ** 2))** 0.5

    def __str__(self):
        return "x=" + str(self.x) + ", y=" + str(self.y)

    def get_line_to(self, target):
        mx = (-target.x + self.x ) 
        my = (-target.y + self.y)
        grad=my/mx
        c=-(grad*(self.x))+self.y
        return grad
    def halfway(self, target):
        """calculating midpoint"""
        mx = (self.x + target.x) / 2
        my = (self.y + target.y) / 2
        return Point(mx, my)

def cencd(p1,p2,p3):
    """calculating the center of a circle"""
    ma=(p2.getY-p1.getY)/(p2.getX-p1.getX)
    mb=(p3.getY-p2.getY)/(p3.getX-p2.getX)
    hw=p1.halfway(p2)
    x=(ma*mb*(p1.getY-p3.getY)+mb*(p1.getX+p2.getX)-ma*(p2.getX+p3.getX))/2*(mb-ma)
    ya=-(1/ma)*((x-hw.getX)+hw.getY)
    return x,ya

"""defining the points for p1,p2 and p3"""

    p = Point(5,5)

    q = Point(6,-2)

    r=Point(2,-4)

    print(cencd(p,q,r))

我收到此错误 message:SyntaxError:函数定义中的参数重复 'p1' 追溯(最近一次通话): 文件 "python",第 45 行,位于 文件 "python",第 34 行,在 cencd 中 TypeError:- 不支持的操作数类型:'method' 和 'method'

请协助。 """working solution """"

ma=(p2.y-p1.y)/(p2.x-p1.x)
mb=(p3.y-p2.y)/(p3.x-p2.x)
hw=p1.halfway(p2)

x1=(ma*mb*(p1.y-p3.y)+mb*(p1.x+p2.x)-ma*(p2.x+p3.x))/(2*(mb-ma))
ya=-(1/ma)*((x1-hw.x))+hw.y

getXgetY 都是代码中的方法,而不是属性。所以你需要使用 getX()getY().

来调用它们

所以ma=(p2.getY-p1.getY)/(p2.getX-p1.getX)变成:

ma = (p2.getY()-p1.getY())/(p2.getX()-p1.getX())

以此类推,其他代码改动

否则,您也可以将方法定义为 @property:

class Point:
    ...
    ...
    @property
    def getX(self):
        return self.x
    @property
    def getY(self):
        return self.y
    ...

现在您可以通过 p1.getXp2.getY 等方式访问它们。

请注意,上面的@属性 装饰器将方法转换为 getter,这仅适用于私有变量(定义为以 _ 开头的变量)。

因此,由于 x 和 y 都是 class 的普通属性,您可以直接访问它们而无需使用和 属性 装饰器或使用 getter 方法,例如 p1.xp2.y,@Padraic 在他的 post.

中指出

您不需要 python 中的 getter 或 setter,使用它们也不是 pythonic,您应该直接访问属性:

def cencd(p1, p2, p3):
    """calculating the center of a circle"""
    ma = (p2.y - p1.y) / (p2.x - p1.x)
    mb = (p3.y - p2.y) / (p3.x - p2.x)
    hw = p1.halfway(p2)
    x = (ma * mb * (p1.y - p3.y) + mb * (p1.x + p2.x) - ma * (p2.x + p3.x)) / 2 * (mb - ma)
    ya = -(1 / ma) * ((x - hw.x) + hw.y)
    return x, ya

正如 Padraic Cunningham 所说,我们在 Python 中不需要 getter 或 setter实际上是根据真实属性计算的。例如,在下面的代码中,我向您的点 class.

添加了一个伪造的 norm 属性

我还添加了一些双下划线方法(又名 dunder methods or magic methods) to your class. These methods are discussed in the official Python docs

最常见的 dunder 方法之一是 __repr__(),它应该 return 一个字符串,该字符串对应于您如何创建 class 的实例。当您在交互式解释器中使用 class 时,这尤其方便。 FWIW,如果 class 没有定义 __str__() 方法,当您尝试将 class 实例转换为字符串时,将使用其 __repr__() 方法。如果未定义 __repr__() 方法,将使用默认方法。

我添加的其他 dunder 方法可以更轻松地对点执行算术运算;这可以使代码更易于编写和阅读。我想您会同意它使 cencd() 函数更清晰一些。 (我不确定该函数到底应该做什么;我假设您的代数是正确的:))。

此代码已在 Python 2.6.6 上测试;它应该 运行 在 Python 3 上正常,无需修改。

#!/usr/bin/env python

''' Point class demo

    From 

    Written by koseph, Padraic Cunningham, and PM 2Ring
    2015.02.19
'''

from __future__ import print_function
from __future__ import division

class Point(object):
    def __init__(self, initX, initY):
        """ Create a new point at the given coordinates. """
        self.x, self.y = initX, initY

    @property
    def norm(self):
        return self.x ** 2 + self.y ** 2

    def distance_from_origin(self):
        return self.norm ** 0.5

    def __repr__(self):
        return 'Point({self.x}, {self.y})'.format(self=self)

    def __str__(self):
        return 'x={self.x}, y={self.y}'.format(self=self)

    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)

    def __mul__(self, scale):
        return Point(self.x * scale, self.y * scale)

    __rmul__ = __mul__

    def __neg__(self):
        return -1 * self

    def __sub__(self, other):
        return self + -other

    def weighted_mean(self, other, weight):
        cweight = 1.0 - weight
        x = cweight * self.x + weight * other.x
        y = cweight * self.y + weight * other.y
        return Point(x, y)

    def halfway(self, other):
        return self.weighted_mean(other, 0.5)


def cencd(p1, p2, p3):
    """ Calculate the center of a circle """
    a = p2 - p1
    b = p3 - p2
    ma = a.y / a.x
    mb = b.y / b.x
    hw = p1.halfway(p2)
    x = ma * mb * (p1 - p3).y + mb * (p1 + p2).x - ma * (p2 + p3).x
    x /= 2.0 * (mb - ma)
    y = -(x - hw.x + hw.y) / ma
    return Point(x, y)


p1 = Point(3, 4)
print(p1)
print('p1 is {0!r}, its norm is {1}'.format(p1, p1.norm))
print('and its distance from the origin is', p1.distance_from_origin(), end='\n\n')

p2 = Point(7, 2)
print('p2 is', repr(p2), end='\n\n')

print('p1 + p2 is', repr(p1 + p2))
print('p1 * 0.1 is', repr(p1 * 0.1))
print('p2 - p1 is', repr(p2 - p1), end='\n\n')

p3 = 4 * p1
print('p3 is', repr(p3), end='\n\n')

print('Weighted means from p1 to p3')
for i in range(5):
    weight = i / 4.0
    print('{0} {1:4.2f} {2!r}'.format(i, weight, p1.weighted_mean(p3, weight)))
print()

print('center of a circle for p1, p2, & p3:', repr(cencd(p1, p2, p3)))

输出

x=3, y=4
p1 is Point(3, 4), its norm is 25
and its distance from the origin is 5.0

p2 is Point(7, 2)

p1 + p2 is Point(10, 6)
p1 * 0.1 is Point(0.3, 0.4)
p2 - p1 is Point(4, -2)

p3 is Point(12, 16)

Weighted means from p1 to p3
0 0.00 Point(3.0, 4.0)
1 0.25 Point(5.25, 7.0)
2 0.50 Point(7.5, 10.0)
3 0.75 Point(9.75, 13.0)
4 1.00 Point(12.0, 16.0)

center of a circle for p1, p2, & p3: Point(8.22727272727, 12.4545454545)