【问题标题】:Python language-center of a circle using OOP使用 OOP 的 Python 语言圆心
【发布时间】:2015-04-20 13:01:33
【问题描述】:
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))

我收到此错误消息:SyntaxError: duplicate argument 'p1' in function definition on on 回溯(最近一次通话最后): 文件“python”,第 45 行,在 文件“python”,第 34 行,在 cencd TypeError: 不支持的操作数类型 -: 'method' 和 'method'

请帮忙。 """工作解决方案""""

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

【问题讨论】:

  • 绝对没有必要使用getter

标签: python class oop python-3.x


【解决方案1】:

在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

【讨论】:

  • 我也用过这个方法和它的清洁器。谢谢
【解决方案2】:

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 等方式访问这些。

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

因此,由于 x 和 y 都是类的普通属性,因此您可以直接访问它们,而无需使用和属性装饰器或使用 getter 方法,如p1.xp2.y,正如@Padraic 在他的帖子中指出的那样。

【讨论】:

  • 非常感谢。今天学到了一些新东西。我一直在 python 代码中看到这个“@”,现在我知道它的用法了。代码工作正常,我只需要使公式正确。非常感谢
【解决方案3】:

正如 Padraic Cunningham 所说,我们在 Python 中不需要 getter 或 setter,但正如 mu 所说,我们可以根据需要制作 getter,但通常它们用于获取“假”属性,这些属性实际上是根据真实属性计算得出的。例如,在下面的代码中,我为您的 Point 类添加了一个伪造的 norm 属性。

我还为您的课程添加了一些双下划线方法(又名dunder 方法或magic methods)。这些方法在the official Python docs 中讨论。

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

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

此代码在 Python 2.6.6 上进行了测试;它应该可以在 Python 3 上运行,无需修改。

#!/usr/bin/env python

''' Point class demo

    From http://stackoverflow.com/q/28602056/4014959

    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)

【讨论】:

  • 感谢您提供解决方案并提出解决此问题的不同方法。我访问了您发布的链接 - 我有一些新内容要阅读。感谢您的贡献。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-23
  • 1970-01-01
  • 2023-01-01
相关资源
最近更新 更多