0
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

when I try to run the above code I get the following error:

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

Quite new to python, cant figure out how to call the function inside class.If anyone can help and explain

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
hampi2017
  • 701
  • 2
  • 13
  • 33

1 Answers1

7

Rename __posDiff to _posDiff (so remove one of the leading underscores).

You are using double underscores at the start of the name, and when using such a name within a class definition, Python mangles that name to produce a class-private name. This feature is used to add a namespace to methods that should not accidentally be overridden in subclasses.

This applies both to method names defined within the class, and any code that tries to use such a name. As such, your reference to __posDiff within the relate method is rewritten to _Circle__posDiff (the class name is prepended to create a namespace), but the __posDiff function itself is itself not re-named because it is not actually inside the class.

See the Reserved classes of identifiers section in the lexical analysis documentation:

__*
Class-private names. Names in this category, when used within the context of a class definition, are re-written to use a mangled form to help avoid name clashes between “private” attributes of base and derived classes. See section Identifiers (Names).

And the linked Identifiers (Names) section in the expressions reference:

Private name mangling: When an identifier that textually occurs in a class definition begins with two or more underscore characters and does not end in two or more underscores, it is considered a private name of that class. Private names are transformed to a longer form before code is generated for them. The transformation inserts the class name, with leading underscores removed and a single underscore inserted, in front of the name. For example, the identifier __spam occurring in a class named Ham will be transformed to _Ham__spam. This transformation is independent of the syntactical context in which the identifier is used.

Bold italic emphasis is mine.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343