45

How can I call a private function from some other function within the same class?

class Foo: def __bar(arg): #do something def baz(self, arg): #want to call __bar 

Right now, when I do this:

__bar(val) 

from baz(), I get this:

NameError: global name '_Foo__createCodeBehind' is not defined 

Can someone tell me what the reason of the error is? Also, how can I call a private function from another private function?

2
  • It does not actually matter here that the function is "private" (this is not real privacy anyway). The problem should have been obvious, anyway: where the code says def baz(self, arg):, why does it not say def baz(arg):? Now, why wouldn't the same logic apply to __bar? Commented Sep 5, 2022 at 10:16
  • @KarlKnechtel stating anything as obvious to someone else is admitting one does not have adequate experience working on a team. This is one of the primary underlying reasons for peer review. See also "agile restrospective prime directive". Commented Oct 13, 2023 at 12:47

2 Answers 2

62

There is no implicit this-> in Python like you have in C/C++ etc. You have to call it on self.

class Foo: def __bar(self, arg): #do something def baz(self, arg): self.__bar(arg) 

These methods are not really private though. When you start a method name with two underscores Python does some name mangling to make it "private" and that's all it does, it does not enforce anything like other languages do. If you define __bar on Foo, it is still accesible from outside of the object through Foo._Foo__bar. E.g., one can do this:

f = Foo() f._Foo__bar('a') 

This explains the "odd" identifier in the error message you got as well.

You can find it here in the docs.

Sign up to request clarification or add additional context in comments.

1 Comment

Consider that making methods private is a communication to developers about how to use the class. Its fine that many languages do not enforce the prevention of access to private members, as the fact that the method is marked as private tells developers not to use the class or instance that way. Developers just need to consider the public interface.
12

__bar is "private" (in the sense that its name has been mangled), but it's still a method of Foo, so you have to reference it via self and pass self to it. Just calling it with a bare __bar() won't work; you have to call it like so: self.__bar(). So...

>>> class Foo(object): ... def __bar(self, arg): ... print '__bar called with arg ' + arg ... def baz(self, arg): ... self.__bar(arg) ... >>> f = Foo() >>> f.baz('a') __bar called with arg a 

You can access self.__bar anywhere within your Foo definition, but once you're outside the definition, you have to use foo_object._Foo__bar(). This helps avoid namespace collisions in the context of class inheritance.

If that's not why you're using this feature, you might reconsider using it. The convention for creating "private" variables and methods in Python is to prepend an underscore to the name. This has no syntactic significance, but it conveys to users of your code that the variable or method is part of implementation details that may change.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.