710

Python gives us the ability to create 'private' methods and variables within a class by prepending double underscores to the name, like this: __myPrivateMethod(). How, then, can one explain this

>>> class MyClass:
...     def myPublicMethod(self):
...             print 'public method'
...     def __myPrivateMethod(self):
...             print 'this is private!!'
... 
>>> obj = MyClass()
>>> obj.myPublicMethod()
public method
>>> obj.__myPrivateMethod()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: MyClass instance has no attribute '__myPrivateMethod'
>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']
>>> obj._MyClass__myPrivateMethod()
this is private!!

What's the deal?!

I'll explain this a little for those who didn't quite get that.

>>> class MyClass:
...     def myPublicMethod(self):
...             print 'public method'
...     def __myPrivateMethod(self):
...             print 'this is private!!'
... 
>>> obj = MyClass()

What I did there is create a class with a public method and a private method and instantiate it.

Next, I call its public method.

>>> obj.myPublicMethod()
public method

Next, I try and call its private method.

>>> obj.__myPrivateMethod()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: MyClass instance has no attribute '__myPrivateMethod'

Everything looks good here; we're unable to call it. It is, in fact, 'private'. Well, actually it isn't. Running dir() on the object reveals a new magical method that python creates magically for all of your 'private' methods.

>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']

This new method's name is always an underscore, followed by the class name, followed by the method name.

>>> obj._MyClass__myPrivateMethod()
this is private!!

So much for encapsulation, eh?

In any case, I'd always heard Python doesn't support encapsulation, so why even try? What gives?

Stefan van den Akker
  • 5,714
  • 7
  • 38
  • 57
willurd
  • 10,421
  • 5
  • 26
  • 22
  • 27
    Same is true for Java or C# if you use reflection (which is somehow what you doing there). – 0x434D53 Feb 22 '15 at 10:24
  • 4
    It was build for Unit Testing purpose, so you can use that "hack" in order to unit test the private methods of your class from outside. – waas1919 Apr 12 '16 at 16:10
  • 22
    Isn't testing private methods an anti-pattern? Private methods will be used in some public method for sure else it's just unused forever. And the right way to test private methods (based on my learning so far from ThoughtWorks) is that you write tests for public methods only that covers all cases. If that works fine, you don't need to test private methods from outside at all. – Vishnu Narang Jan 22 '17 at 23:19
  • 5
    @VishnuNarang: Yeah, that's whats often teached. But As always, an almost "religious" approach of "*always* do this, *never* do that" is the only thing that "never" is good. If unit tests are "only" used for regression tests or testing public API, you don't need to test privates. But if you do unit test driven development, there are good reasons to test privat methods during development (for example when it's hard to mock certain unusual / extreme parameters through the public interface). Some languages / unit test environments don't let you do this, which IMHO is not good. – Marco Freudenberger Feb 13 '17 at 14:25
  • 8
    @MarcoFreudenberger I see your point. I do have experience in unit test driven development. Often when it becomes difficult to mock parameters, most often it's resolved by changing and improving the design. I'm yet to come across a scenario where the design is perfect and still unit testing is extremely difficult to avoid testing private methods. I'll look out for such cases. Thanks. I'd appreciate if you could maybe share one scenario off the top of your head to help me understand. – Vishnu Narang Feb 13 '17 at 18:56
  • 1
    I don't have a good scenario at hand that does not involve external hardware directly or indirectly (For example, I'm working on vision systems a lot, for certain values passed to private methods, certain images would need to be created - which can be hard - because the public interface would take images originating from a camera or from a set of test images in case of unit tests). – Marco Freudenberger Feb 14 '17 at 20:21
  • 2
    Realy nice idea this "we're all consenting adults" thing. Fact is: in a group of programmers sufficient enough, just like in any other group, wisdom is not spread equally. If everybody would know everything stackoverflow would not exist. Here is another quote: "I came for the philosophy and left for the reallity". – omni May 23 '18 at 19:16
  • 2
    @masi Plus if you're more than the simplest code monkey, you'll have to juggle several things in your mind while programming. Clean coders make methods small in order to not have to keep too many things in mind. If I have to emulate type-safety in my head, that's one more thing taking away from focusing on architecture and algorithms. – Raphael Schmitz Feb 20 '19 at 09:57
  • 1
    By exposing private methods, python seem to prefer 'Liver hanging out of rib-cage', though it is given a spin,'We are all adults, In Python We Trust'. – Espresso Jul 19 '19 at 02:38

13 Answers13

630

The name scrambling is used to ensure that subclasses don't accidentally override the private methods and attributes of their superclasses. It's not designed to prevent deliberate access from outside.

For example:

>>> class Foo(object):
...     def __init__(self):
...         self.__baz = 42
...     def foo(self):
...         print self.__baz
...     
>>> class Bar(Foo):
...     def __init__(self):
...         super(Bar, self).__init__()
...         self.__baz = 21
...     def bar(self):
...         print self.__baz
...
>>> x = Bar()
>>> x.foo()
42
>>> x.bar()
21
>>> print x.__dict__
{'_Bar__baz': 21, '_Foo__baz': 42}

Of course, it breaks down if two different classes have the same name.

Alya
  • 6,316
  • 1
  • 14
  • 3
  • 13
    http://docs.python.org/2/tutorial/classes.html. Section:9.6 on Private variables and class-local references. – gjain Oct 17 '13 at 00:41
  • 78
    For those of us too lazy to scroll/search: [Section 9.6 direct link](http://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references) – cod3monk3y Feb 20 '14 at 04:22
  • Nice--a positive reason! I had read/heard that this was just to discourage deliberate access from outside (without actually blocking it). Glad to see that there are additional benefits too. – Jon Coombs Mar 15 '14 at 06:49
  • 3
    You should put a single underscore to specify that the variable should be considered as private. Again, this does not prevent someone from actually accessing that. – igon Sep 29 '14 at 21:31
  • @miya oh yeah this is so, and he got that from [documentation](https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references) – Sнаđошƒаӽ Jan 15 '16 at 17:55
  • 20
    [Guido answered this question](https://plus.google.com/115212051037621986145/posts/7wpbQTPRWft) - "main reason for making (nearly) everything discoverable was debugging: when debugging you often need to break through the abstractions" - I added it as comment because it's too late -- too many answers. – Peter M. - stands for Monica Feb 01 '16 at 19:02
  • 2
    If you go by the "prevent deliberate access" criterion, most OOP languages don't support truly private members. For example in C++ you have raw access to memory and in C# trusted code can use private reflection. – CodesInChaos Jul 13 '16 at 10:40
  • 1
    This is why I never dunders in classes whose interface was designed by me. Everyone who might be subclassing it, knows what he's working on and will most likely have a reason to overload certain things, so one underscore is enough to make methods and properties private. I do use dunders when implementing interfaces designed by others though, as to not clutter the api and prevent errors in case they are subclassed based on knowledge about their ABS. A good reason to use dunders is, for example, an implementation of `io.BufferedIOBase`, where nothing should interfere with the buffers. – Bachsau Nov 28 '18 at 16:09
  • Update from Python 3.4: A name prefixed with an underscore (e.g. _spam) should be treated as a non-public part of the API (whether it is a function, a method or a data member). It should be considered an implementation detail and subject to change without notice. https://docs.python.org/3/tutorial/classes.html#tut-private – Moradnejad Nov 24 '20 at 11:11
211

Example of private function

import re
import inspect

class MyClass :

    def __init__(self) :
        pass

    def private_function ( self ) :
        try :
            function_call = inspect.stack()[1][4][0].strip()

            # See if the function_call has "self." in the begining
            matched = re.match( '^self\.', function_call )
            if not matched :
                print 'This is Private Function, Go Away'
                return
        except :
            print 'This is Private Function, Go Away'
            return

        # This is the real Function, only accessible inside class #
        print 'Hey, Welcome in to function'

    def public_function ( self ) :
        # i can call private function from inside the class
        self.private_function()

### End ###
cwallenpoole
  • 72,280
  • 22
  • 119
  • 159
arun
  • 2,215
  • 1
  • 12
  • 3
  • 12
    `self = MyClass()` `self.private_function()`. :D Of course it doesn't work in classes, but you just have to define a custom function: `def foo(self): self.private_function()` – Casey Kuball May 08 '12 at 16:34
  • 184
    Just in case it wasn't clear: *never* do this in real code ;) – Sudo Bash Jul 12 '13 at 15:40
  • 2
    I wouldn't bother loading regex just to test a `/^.../` expression, save some time and use `0 == function_call.index('self.')` – ThorSummoner Jul 02 '14 at 23:32
  • 10
    @ThorSummoner Or just `function_call.startswith('self.')`. – nyuszika7h Aug 27 '14 at 08:52
  • 14
    `inspect.stack()[1][4][0].strip()` – akhy Jun 23 '16 at 07:36
  • 3
    `self` is only a convention. one may use a different name for first argument – akiva Jul 18 '16 at 00:40
  • 2
    @arun, Why 1 4 0? – Iulian Onofrei Apr 21 '17 at 13:45
  • but when I am calling obj.public_function() ... it is still showing 'This is Private Function, Go Away'. should not it show 'welcome in to function' – Jai May 30 '17 at 08:11
  • @SudoBash - idiot question: why not use this in real code? – Shuklaswag Feb 07 '18 at 19:28
  • 2
    @Shuklaswag This makes your code harder to work with since it put obstacles in the way of anyone debugging it. Trying to bypass a language's rules with unnecessary cleverness rarely ends well. (It also doesn't really block public calls to the function). – Will Nov 22 '18 at 02:49
  • 5
    This can be defeated quite easily by doing `self = MyClass(); self.private_function()` and it fails when called using `x = self.private_function()` inside a method. – Will Nov 22 '18 at 02:58
  • 1
    not sure if I understand this answer. It demonstrates how to have a truly private method, but does not answer the question "why pyhthon has no truly private methods?", right? – 463035818_is_not_a_number Jan 22 '19 at 15:34
190

When I first came from Java to Python I hated this. It scared me to death.

Today it might just be the one thing I love most about Python.

I love being on a platform, where people trust each other and don't feel like they need to build impenetrable walls around their code. In strongly encapsulated languages, if an API has a bug, and you have figured out what goes wrong, you may still be unable to work around it because the needed method is private. In Python the attitude is: "sure". If you think you understand the situation, perhaps you have even read it, then all we can say is "good luck!".

Remember, encapsulation is not even weakly related to "security", or keeping the kids off the lawn. It is just another pattern that should be used to make a code base easier to understand.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Thomas Ahle
  • 28,005
  • 19
  • 77
  • 105
  • 37
    @CamJackson Javascript is your example?? The only widely used language that has prototybe-based inheritance and a language that favors functional programming? I think JS is a lot harder to learn than most of the other languages, since it takes several orthogonal steps from traditional OOP. Not that this prevents idiots from writing JS, they just don't know it ;) – K.Steff Apr 10 '12 at 01:45
  • @Sudar Yes, when we're talking about the culture of forcing programmers to write things in a certain way, Java is probably a better 'opposite' to Python in that regard. But Javascript annoys me in other ways :P (see my last comment) – Cam Jackson Jun 22 '12 at 11:16
  • 29
    APIs are actually a really good example of why encapsulation matters and when private methods would be preferred. A method intended to be private may go away, change signature, or worst of all change behavior -- all without warning -- on any subsequent new version. Will your smart, adult team member really remember that she accessed an intended-to-be-private method a year from now when you update? Will she even be working there anymore? – einnocent Jan 10 '14 at 00:35
  • 5
    I disagree with the argument. In production code, I would most probably never use an API that has a bug that makes me change public members to make it "work". An API should work. If it doesn't, I would file a bug report or make the same API myself. I don't like the philosophy and I am not very fond of Python, although its syntax makes it fun to write smaller scripts in... – Yngve Sneen Lindal Feb 19 '14 at 11:45
  • 1
    No one forces you to use undocumented APIs, but if you want it, who's to tell you no to? Unit testing comes to mind as a use case. – Thomas Ahle Apr 08 '14 at 13:07
  • 4
    Java has Method.setAccessible and Field.setAccessible. Also scary? – Tony Apr 24 '14 at 17:15
  • 22
    The enforcement in Java and C++ is not because Java distrusts the user whilst Python does. Its because the compiler and/or vm can make various assumptions when dealing with how it goes about its business if it knows this information, for instance C++ can skip an entire layer of indirection by using regular old C calls instead of virtual calls, and that matters when your working on high performance or high precision stuff. Python by its nature can't really make good use of the information without compromising its dynamism. Both languages are aiming at different things, so neither are "wrong" – Shayne Sep 04 '16 at 11:25
  • 2
    I'm the opposite of your comment. I came from python, and started picking up Java and C++. Private isn't about not trusting your team mates. W/o it common mistakes happen, where a new dev on the team accesses a method outside the scope of business logic. something that should be private and called specifically through some logic, is now public and can be called from the outside. even more scary is when the dev making this mistake is doing it on a public endpoint, opening an app to sec. vulnerabilities. I like python, but i hate this aspect of it. – continuousqa Mar 01 '19 at 17:12
  • 2
    It most def. can be a sec. flaw. devs come and go on teams. a dev can be tasked with adding a public endpoint that allows affiliates to pass new registrants for user creation. However said dev, repurposes account creation done by other devs. account creation class calls several methods that validate domains for fraud. But this new dev directly accesses the final method, passing in a value for domain validation. now the public endpoint bypasses fraud checks. Had that final method been private, none of that would happen. it would force it to flow through the bus. logic. – continuousqa Mar 01 '19 at 17:18
  • 2
    We dont make methods private and public for security's sake. We do them to prevent users from fatally injuring state and writing programs using volatile methods.. A public method represents a contract, if I give you A you will output B. Private methods do not represent a contract. I can change the logic that turns A into B as much as I need to so long as the interface to the interaction still fulfills the contract. If I give you access to private methods, you will use them. Then when I change implementation, your program breaks. Doesn't happen with public methods that form a contract. – TheBatman Apr 23 '19 at 18:11
  • "_I love being on a platform, where people trust each other and don't feel like they need to build impenetrable walls around their code._" Utter nonsense. Throwing away established design principles doesn't make your coworkers fall in love with you, it's quite the opposite. Python, in many ways, will never achieve the structure and formalism of typed JVM languages, or the functional flair of Haskell. It's good for some things, but no need to put lipstick on a pig. – Abhijit Sarkar Aug 26 '20 at 01:14
  • @einnocent It doesn't convince me that private method can change any time without notification. Actually the same could be applied to Python, https://docs.python.org/3/tutorial/classes.html#tut-private, `_underscore_method()` should be considered as implementation detail. So the class consumer should take a note that it can change any time. If someone is using your private methods in his production code then it's not your problem if you change your private stuff. – Qback Aug 31 '20 at 17:20
  • 1
    The biggest mistake of Java was not to distinguish between public and published method (method that are supposed to be called from outside the jar), python compound on that mistake making everything visible. In any big enough project makes release and dependencies management a complete nightmare (add on top that some errors can only be discovered in run-time and ticking bomb is served) – Alessandro Teruzzi Sep 18 '20 at 11:04
148

From http://www.faqs.org/docs/diveintopython/fileinfo_private.html

Strictly speaking, private methods are accessible outside their class, just not easily accessible. Nothing in Python is truly private; internally, the names of private methods and attributes are mangled and unmangled on the fly to make them seem inaccessible by their given names. You can access the __parse method of the MP3FileInfo class by the name _MP3FileInfo__parse. Acknowledge that this is interesting, then promise to never, ever do it in real code. Private methods are private for a reason, but like many other things in Python, their privateness is ultimately a matter of convention, not force.

xsl
  • 16,188
  • 16
  • 69
  • 111
  • 207
    or as Guido van Rossum put it: "we are all adults." –  Oct 06 '08 at 11:20
  • 37
    -1: this is just wrong. Double underscores is never meant to be used as private in first place. The answer from Alya below tells the real intention of name mangling syntax. The real convention is a single underscore. – nosklo Oct 15 '09 at 14:02
  • 2
    Try with one underscore only and you will see the result you get. @nosklo – Billal Begueradj Feb 07 '17 at 09:56
96

The phrase commonly used is "we're all consenting adults here". By prepending a single underscore (don't expose) or double underscore (hide), you're telling the user of your class that you intend the member to be 'private' in some way. However, you're trusting everyone else to behave responsibly and respect that, unless they have a compelling reason not to (e.g. debuggers, code completion).

If you truly must have something that is private, then you can implement it in an extension (e.g. in C for CPython). In most cases, however, you simply learn the Pythonic way of doing things.

Tony Meyer
  • 9,361
  • 5
  • 38
  • 47
  • so is there some sort of wrapper protocol that I'm supposed to use to access a protected variable? – intuited May 10 '10 at 18:56
  • 3
    There aren't "protected" variables any more than there are "private". If you want to access an attribute that starts with an underscore, you can just do it (but note that the author discourages this). If you must access an attribute that starts with a double underscore, you can do the name mangling yourself, but you almost certainly do not want to do this. – Tony Meyer May 13 '10 at 08:41
33

It's not like you absolutly can't get around privateness of members in any language (pointer arithmetics in C++, Reflections in .NET/Java).

The point is that you get an error if you try to call the private method by accident. But if you want to shoot yourself in the foot, go ahead and do it.

Edit: You don't try to secure your stuff by OO-encapsulation, do you?

Maximilian
  • 4,460
  • 5
  • 26
  • 28
  • 2
    Not at all. I'm simply making the point that it's odd to give the developer an easy, and in my opinion way to magical, way of accessing 'private' properties. – willurd Sep 16 '08 at 09:11
  • 2
    Yeah, I just tried to illustrate the point. Making it private just says "you shouldn't access this directly" by making the compiler complain. But one wants to really really do it he can. But yes, it's easier in Python than in most other languages. – Maximilian Sep 16 '08 at 09:26
  • 7
    In Java, you actually can secure stuff via encapsulation, but that requires you to be smart and run the untrusted code in a SecurityManager, and be very careful. Even Oracle gets it wrong sometimes. – Antimony Apr 24 '13 at 01:16
13

The class.__stuff naming convention lets the programmer know he isn't meant to access __stuff from outside. The name mangling makes it unlikely anyone will do it by accident.

True, you still can work around this, it's even easier than in other languages (which BTW also let you do this), but no Python programmer would do this if he cares about encapsulation.

Nickolay
  • 28,261
  • 8
  • 94
  • 160
13

Similar behavior exists when module attribute names begin with a single underscore (e.g. _foo).

Module attributes named as such will not be copied into an importing module when using the from* method, e.g.:

from bar import *

However, this is a convention and not a language constraint. These are not private attributes; they can be referenced and manipulated by any importer. Some argue that because of this, Python can not implement true encapsulation.

Ross
  • 1,397
  • 9
  • 10
12

It's just one of those language design choices. On some level they are justified. They make it so you need to go pretty far out of your way to try and call the method, and if you really need it that badly, you must have a pretty good reason!

Debugging hooks and testing come to mind as possible applications, used responsibly of course.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
ctcherry
  • 26,534
  • 5
  • 61
  • 70
11

Important update (Python 3.4):

Any identifier of the form __name (at least two leading underscores, at most one trailing underscore) is publicly replaced with _classname__name, where classname is the current class name with leading underscore(s) stripped.

Therefore, __name is private, while _classname__name is public.

https://docs.python.org/3/tutorial/classes.html#tut-private

Example

class Cat:
    def __init__(self, name='unnamed'):
        self.name = name
    def __print_my_name(self):
        print(self.name)
        
        
tom = Cat()
tom.__print_my_name() #Error
tom._Cat__print_my_name() #Prints name
Moradnejad
  • 2,622
  • 1
  • 23
  • 50
4

With Python 3.4 this is the behaviour:

>>> class Foo:
        def __init__(self):
                pass
        def __privateMethod(self):
                return 3
        def invoke(self):
                return self.__privateMethod()


>>> help(Foo)
Help on class Foo in module __main__:

class Foo(builtins.object)
 |  Methods defined here:
 |
 |  __init__(self)
 |
 |  invoke(self)
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |
 |  __dict__
 |      dictionary for instance variables (if defined)
 |
 |  __weakref__
 |      list of weak references to the object (if defined)

 >>> f = Foo()
 >>> f.invoke()
 3
 >>> f.__privateMethod()
 Traceback (most recent call last):
   File "<pyshell#47>", line 1, in <module>
     f.__privateMethod()
 AttributeError: 'Foo' object has no attribute '__privateMethod'

https://docs.python.org/3/tutorial/classes.html#tut-private

Note that the mangling rules are designed mostly to avoid accidents; it still is possible to access or modify a variable that is considered private. This can even be useful in special circumstances, such as in the debugger.

Even if the question is old I hope my snippet could be helpful.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Alberto
  • 694
  • 4
  • 17
4

The most important concern about private methods and attributes is to tell developers not to call it outside the class and this is encapsulation. one may misunderstand security from encapsulation. when one deliberately uses syntax like that(bellow) you mentioned, you do not want encapsulation.

obj._MyClass__myPrivateMethod()

I have migrated from C# and at first it was weird for me too but after a while I came to the idea that only the way that Python code designers think about OOP is different.

Afshin Amiri
  • 2,842
  • 1
  • 15
  • 20
1

Why are Python's 'private' methods not actually private?

As I understand it, they can't be private. How could privacy be enforced?

The obvious answer is "private members can only be accessed through self", but that wouldn't work - self is not special in Python, it is nothing more than a commonly-used name for the first parameter of a function.

user200783
  • 12,313
  • 10
  • 58
  • 110