2

I am writing a banking application in Python, and reading some source code from here Banking Application. The balance class is defined below:

class Balance(object):
    """ the balance class includes the balance operations """

    def __init__(self):
        """ instantiate the class """
        self.total = 0

    def add(self, value):
        """ add value to the total
        Args:
            value (int): numeric value
        """
        value = int(value)
        self.total += value

    def subtract(self, value):
        """ subtract value from the total
        Args:
            value (int): numeric value
        """
        value = int(value)
        self.total -= value

My Question

Since balance details should not be accessed outside of a class, we should be defining the attribute self.total as self.__total since we should make it a private rather public variable? Is my line of thinking correct here?

python
  • 4,403
  • 13
  • 56
  • 103
  • 4
    There is no such thing as a private member variable in Python. Double underscore names are meant to avoid accidental overriding by a subclass instead. – Martijn Pieters Jan 10 '16 at 03:22
  • 1
    Yep. You would still be able to access self.__total, but it would be under the name `B = Balance(); B._Balance__total`. – Reti43 Jan 10 '16 at 03:24
  • I was watching this [video](https://www.youtube.com/watch?v=Wi4bGaUTItY0) – python Jan 10 '16 at 03:24
  • How should I ensure that my attribute `self.total` is not accessed by anyone else then? – python Jan 10 '16 at 03:26
  • 2
    See [The meaning of a single- and a double-underscore before an object name in Python](http://stackoverflow.com/q/1301346) – Martijn Pieters Jan 10 '16 at 03:31
  • 2
    @python: you don't. You name it `_total`, which *documents* that other code shouldn't access it. But you can't *prevent* access, Python expects everyone to behave like responsible adults instead. – Martijn Pieters Jan 10 '16 at 03:32
  • 1
    Also see [Does Python have “private” variables in classes?](http://stackoverflow.com/q/1641219) – Martijn Pieters Jan 10 '16 at 03:33
  • @MartijnPieters Thanks for helpful info. Didn't knew that!! – python Jan 10 '16 at 03:33

1 Answers1

7

In short: there is no way to have a truly "private" class member in Python. The runtime simply doesn't support memory protection in the way, ex, Java does.

The double underscore prefix mangles the name so it includes the name of the class it's used in (ex, __total would become _Balance__total), but this is primarily used to allow subclasses to define names which appear the same, but reference different fields.

The standard convention in Python is to use a single underscore prefix — _total — for class members which should be treated as be "private" or "protected", then trust that the other developers will be adults and respect that (of course, this isn't always a safe assumption…)

It is very rare to see modern Python code use double-underscore attributes.

David Wolever
  • 148,955
  • 89
  • 346
  • 502
  • 2
    [Reference link](http://stackoverflow.com/questions/6930144/underscore-vs-double-underscore-with-variables-and-methods) for additional reading. – Reti43 Jan 10 '16 at 03:27
  • You are saying there is no way to protect my variable `self.total` from unauthorized access? – python Jan 10 '16 at 03:30
  • 2
    Nope. As I say in the last paragraph, Python does assume that the developers working on code will not be malicious. – David Wolever Jan 10 '16 at 03:31