【问题标题】:Call python method defined out of class within the class在类内调用类外定义的python方法
【发布时间】:2016-09-07 21:07:24
【问题描述】:
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

当我尝试运行上述代码时,出现以下错误:

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

对python很陌生,不知道如何在类中调用函数。如果有人可以帮忙解释一下

【问题讨论】:

标签: python


【解决方案1】:

__posDiff 重命名为 _posDiff(因此删除前导下划线之一)。

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

这既适用于类中定义的方法名称,也适用于任何尝试使用此类名称的代码。因此,您在relate 方法中对__posDiff 的引用被重写为_Circle__posDiff(类名被添加到创建命名空间的前面),但__posDiff 函数本身并没有被重新命名,因为它不是实际上在课堂内。

参见词法分析文档中的Reserved classes of identifiers section

__*
类私有名称。此类别中的名称,当在类定义的上下文中使用时,会被重新编写以使用重整形式,以帮助避免基类和派生类的“私有”属性之间的名称冲突。见Identifiers (Names)部分。

以及表达式参考中链接的Identifiers (Names) section

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

粗斜体强调是我的。

【讨论】:

  • 感谢 Martijn,这真的很有帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-16
  • 1970-01-01
  • 1970-01-01
  • 2010-11-19
  • 1970-01-01
  • 2017-07-15
相关资源
最近更新 更多