Private in Python with double underscore instead of one underscore


Updated that I was wrong about private variable in Python and get corrected by my friends : http://eugene-yeo.me/

I believe there are a few people thinking single underscore “_” is for create private variable in Python. Well, this is not right anyway. To make it easy for explaining, let see this socket modules in Python
http://svn.python.org/projects/python/trunk/Lib/socket.py at this line:

1
2
3
4
import _socket
from _socket import *
from functools import partial
from types import MethodType

We will thing that this socket module try to import _socket.py. Well, this wrong anyway. That’s mean it will import C-Extensions socket module.

Then what the purpose for single underscore in Python?
Based on PEP, it use for calling non-public part of the API.

Then, how to create private variable in Python?
We using __ (double underscore)

This is the example code:

1
2
3
4
5
6
7
8
9
10
11
12
class Example():
    def __init__(self):
        self._semiprivate = "HELLO"
        self.__privateall = "WORLD"

if __name__ == "__main__":
    e = Example()
    print e._semiprivate
    try:
        print e.__privateall
    except AttributeError:
        print e.__dict__

WARNING: This is wrong, based on pep 0008 there no such as private variable in Python, hence term “private” not used in Python. Here is the correction:

1. Single lead underscore ( _ )
This is weak variable, then means if your have module that have varible with single leading underscore, this variable will not called from another module which import this module.

2. Double lead underscore ( __ )
If your class intented to be subclassed and don’t want attribute inside class can be used by subclassed, then use __ which I was mistakenly thinking this is called “private”.

To prove I’m wrong, here is the same scripts :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Example():
    def __init__(self):
        self._semiprivate = "HELLO"
        self.__privateall = "WORLD"

if __name__ == "__main__":
    e = Example()
    print e._semiprivate
    try:
        print e.__privateall
    except AttributeError:
        print e.__dict__

    print e._Example__privateall

For double underscore, it will called as name mangling and not everyone like to use it.


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.