2

The following code shows no error.

class Bar():
    pass

class Foo():
    def __init__(self):
        self.__bar = Bar()

    def get_bar(self):
        return self.__bar

foo = Foo()
bar1 = foo.get_bar()

foo.__bar = Bar()
bar2 = foo.get_bar()

assert (bar1 is bar2)

Why is __bar acting like a singleton?

martineau
  • 119,623
  • 25
  • 170
  • 301
Shaung
  • 508
  • 4
  • 11

1 Answers1

4

Because double underscores are magical: Python mangles these names so that they can't be accessed from outside the class.

If you were to replace the last three lines of your example with...

foo._Foo__bar = Bar()
bar2 = foo.get_bar()

assert (bar1 is bar2)

...you would see the behavior you expect.

larsks
  • 277,717
  • 41
  • 399
  • 399
  • or if you implemented a `set_bar` method which sets `self.__foo`. – Daniel Roseman Aug 11 '16 at 11:56
  • To emphasize what Daniel said in his comment, implementing a `set_bar` method is the correct way to do it. The example in this answer was just to demonstrate the name mangling. – larsks Aug 11 '16 at 12:34