【问题标题】:Python find method in classPython在类中查找方法
【发布时间】:2013-05-08 15:11:30
【问题描述】:

我定义了一个名为 Point 的类,它定义了 x、y 坐标系中的一个点。定义和方法如下所示。我创建了自己的 str 方法版本,以可打印的形式返回创建的点(必需)。但是,当我尝试使用调用 p.DistanceTo(p2) 将返回的点传递给另一个方法来确定两点(p1 和 p2)之间的距离时,尝试解析字符串(p2 ) 传入方法中:

AttributeError: Point instance has no attribute 'find'

当我传入一个定义为 p2 的字符串时,它应该可以正常工作。任何帮助将不胜感激。谢谢。

代码如下:

class Point:
    """ Define a Point
    """
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

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

    def __getitem__(self,i):
        return i

    def __find__(self,j):
        return j

    def DistanceTo(self,p2):
        idx1 = p2.find("(")
        idx2 = p2.find(",")
        idx3 = p2.find(")")

        x2 = int(p2[idx1+1:idx2])
        y2 = int(p2[idx2+1:idx3])

        dist = math.sqrt(math.pow((x2-self.x),2)+math.pow((y2-self.y),2))
        return  dist


p1=Point()

p2=Point(3,4)

print p1.DistanceTo(p2)

【问题讨论】:

    标签: python class definition


    【解决方案1】:

    您将方法命名为 __find__。去掉双下划线:

    def find(self, j):
        return j
    

    您真的应该只为Special method names 使用__...__“dunder”(双下划线)方法名称,以避免混淆和未来的名称冲突。

    但是,您传入的是 Point 实例,因此只需直接访问属性即可:

    def DistanceTo(self,p2):
        x2 = p2.x
        y2 = p2.y
    
        dist = math.sqrt(math.pow((x2-self.x),2)+math.pow((y2-self.y),2))
        return  dist
    

    或者,进一步简化,使用 Python 中最常用于方法的 underscore_name 样式:

    def distance_to(self, p2):
        return math.sqrt(math.pow((p2.x - self.x), 2) + math.pow((p2.y - self.y), 2))
    

    然后您可以删除 __find____getitem__ 方法,这些看起来像是在尝试使 .DistanceTo() 方法工作。

    整个班级就变成了:

    class Point(object):
        """Define a Point"""
    
        def __init__(self, x=0, y=0):
            self.x = x
            self.y = y
    
        def __str__(self):
            return "({0.x}, {0.y})".format(self)
    
        def distance_to(self, p2):
            return math.sqrt(math.pow((p2.x - self.x), 2) + math.pow((p2.y - self.y), 2))
    

    对类(继承自object)和__str__ 方法(使用字符串格式)使用更多的Python 习惯用法。

    现在该类的行为符合预期:

    >>> p1 = Point()
    >>> p2 = Point(3,4)
    >>> print p1
    (0, 0)
    >>> print p2
    (3, 4)
    >>> print p1.distance_to(p2)
    5.0
    

    类实例不是字符串,尽管它们可以转换为字符串(例如打印时),但您不需要将它们视为字符串。直接访问它们的属性即可。

    【讨论】:

    • 写下你答案的第一部分。不会将方法更改为find 只是返回参数?因此,p2.find('(') 将返回 ( 而不是预期值 - str 返回值中( 的索引。
    • x2 = p2[idx1+1:idx2] TypeError: cannot concatenate 'str' and 'int' objects
    • @sberry:是的,这就是我们下半场要解决的问题。
    • @user2278537:查看更新; p2 不是字符串,也不需要像字符串一样。
    【解决方案2】:

    你的对象中没有声明方法find,你必须像这样改变find方法声明:

    ...
    def find(self,j):
        return j
    ...
    

    双下划线保留给类运算符方法,如 str、cmp、eq 等... 你可以得到更多关于python类的信息here

    【讨论】:

    • 嘿伙计们,当我尝试解析 p2 字符串时出现此错误:x2 = p2[idx1+1:idx2] TypeError: cannot concatenate 'str' and 'int' objects
    • 如果要将 int 对象与另一个 str 连接,则需要将其转换为 str。如果要将 int 对象转换为 str 使用 str() 内置函数。例如:a=1; aConvertedToStr=str(a)
    • 感谢所有帮助我更好地理解 Python 的人。我喜欢这种语言!
    【解决方案3】:

    如果您打算在您的类中使用私有或半私有方法,请重命名您的函数。

    如果您的 find 方法仅在 Point 类中使用,请将其重命名为 __find。否则,您可以将其重命名为 _find,这会告诉其他开发人员此方法是私有的,但即使他们不应该使用它,他们仍然可以使用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-06
      • 2017-02-21
      • 2021-06-14
      • 2012-07-09
      • 1970-01-01
      • 1970-01-01
      • 2014-11-03
      相关资源
      最近更新 更多