调用类中定义的类外的python方法

dex*_*007 0 python

import math

class Circle(object):    
    def __init__(this,x,y,rad):
        this.x=x
        this.y=y
        this.rad=rad

    def relate(circ1,circ2):
        diff=__posDiff((circ1.x,circ1.y),(circ2.x,circ2.y))
        print diff

def __posDiff(p1,p2):
    diff=math.sqrt((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2)
    return diff
Run Code Online (Sandbox Code Playgroud)

当我尝试运行上面的代码时,我收到以下错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "Circle.py", line 18, in relate
    diff=__posDiff((circ1.x,circ1.y),(circ2.x,circ2.y))
NameError: global name '_Circle__posDiff' is not defined
Run Code Online (Sandbox Code Playgroud)

相当新的python,无法弄清楚如何在类中调用函数.如果有人可以帮助和解释

Mar*_*ers 7

重命名__posDiff_posDiff(因此删除一个前导下划线).

您在名称的开头使用双下划线,并且在类定义中使用这样的名称时,Python会破坏该名称以生成类 - 私有名称.此功能用于向不应在子类中意外覆盖的方法添加命名空间.

这适用于类中定义的方法名称以及尝试使用此类名称的任何代码.因此,您__posDiffrelate方法中的引用被重写为_Circle__posDiff(类名称被添加到创建命名空间之前),但__posDiff函数本身本身没有被重命名,因为它实际上不在类中.

请参阅词法分析文档中的保留类标识符部分:

__*
类私有名称.当在类定义的上下文中使用时,此类别中的名称将被重写以使用损坏的表单来帮助避免基类和派生类的"私有"属性之间的名称冲突.请参阅标识符(名称)部分.

并且表达式中的链接标识符(名称)部分引用:

专用名称修改:当在类定义中以文本方式出现的标识符以两个或多个下划线字符开头且不以两个或多个下划线结尾时,它将被视为该类的私有名称.在为其生成代码之前,将私有名称转换为更长的形式.转换将在名称前面插入类名,删除前导下划线并插入单个下划线.例如,__spam名为Ham的类中的标识符将转换为_Ham__spam.此转换独立于使用标识符的语法上下文.

大胆的斜体重点是我的.