7

I recently posted a question on stackoverflow and I got a resolution.

Some one suggested to me about the coding style and I haven't received further input. I have the following question with reference to the prior query.

  1. How can we declare private variables inside a class in python? I thought that by using a double underscore (__) the variable is treated as private. Please correct me.

  2. As per the suggestion received before, we don't have to use a getter or setter method. Shouldn't we use a getter or setter or both? Please let me know your suggestion on this one.

Community
  • 1
  • 1
techrawther
  • 163
  • 3
  • 15
  • 2
    The answer to #1 is, there are no true private variables in Python. See: [this](http://stackoverflow.com/questions/70528/why-are-pythons-private-methods-not-actually-private) and [this](http://stackoverflow.com/questions/7456638/true-privateness-in-python/7456669#7456669) – NullUserException Oct 05 '11 at 01:45
  • 2
    http://dirtsimple.org/2004/12/python-is-not-java.html – SingleNegationElimination Oct 05 '11 at 01:51

5 Answers5

10

Everything is public in Python, the __ is a suggestion by convention that you shouldn't use that function as it is an implementation detail.

This is not enforced by the language or runtime in any way, these names are decorated in a semi-obfuscated way, but they are still public and still visible to all code that tries to use them.

Idiomatic Python doesn't use get/set accessors, it is duplication of effort since there is no private scope.

You only use accessors when you want indirect access to a member variable to have code around it, and then you mark the member variable with __ as the start of its name and provide a function with the actual name.

You could go to great lengths with writing reams of code to try and protect the user from themselves using Descriptors and meta programming, but in the end you will end up with more code that is more to test and more to maintain, and still no guarantee that bad things won't happen. Don't worry about it - Python has survived 20 years this way so far, so it can't be that big of a deal.

codeforester
  • 39,467
  • 16
  • 112
  • 140
  • Thanks Jarrod.If we cannot assign a variable private how can we enforce rules like variable should not be receiving unacceptable values – techrawther Oct 05 '11 at 01:48
  • 1
    You can't really enforce it. If they want to access it, they will. Double underscore merely tries to obfuscate it with how it generates the naming when you look at the attributes from outside the class – jdi Oct 05 '11 at 01:49
  • There are some [meta programming techniques](http://www.acooke.org/cute/PythonMeta0.html) that you can use to intercept accesses to member variables, but honestly, in 15 years of Python programming it has never been a hinderence to me, or the rest of the world really. –  Oct 05 '11 at 01:52
  • 2
    `__` is not just a convention. Single underscore is but double underscore adds attribute name mangling. Every such attribute (`__foo`) is translated into `_ClassName__foo` when used inside the `class` block. Extensive use of this feature quickly makes the code hard to read and confusing. Most of the time, single underscore is sufficient as a hint. – yak Oct 05 '11 at 02:37
  • So if you see someone doing `module._foo()` then tell them they do it on their own risk as they access a "private" method/function? – Roland Jun 04 '23 at 04:54
5

PEP 8 (http://www.python.org/dev/peps/pep-0008/) has a section "Designing for inheritance" that should address most of these concerns.

To quote:

"We don't use the term "private" here, since no attribute is really private in Python (without a generally unnecessary amount of work)."

Also:

"If your class is intended to be subclassed, and you have attributes that you do not want subclasses to use, consider naming them with double leading underscores and no trailing underscores."

If you've not read the entire section, I would encourage you to do so.

Update:

To answer the question (now that the title has changed). The pythonic way to use private variables, is to not use private variables. Trying to hide something in python is seldom seen as pythonic.

Adam Wagner
  • 15,469
  • 7
  • 52
  • 66
1

You can use Python properties instead of getters and setters. Just use an instance attribute and when you need something more complex, make this attribute a property without changing too much code.

http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/

iurisilvio
  • 4,868
  • 1
  • 30
  • 36
0

Private variables:

If you use the double underscore at the beginning of your class members they are considered to be private, though not REALLY enforced by python. They simply get some naming tacked on to the front to prevent them from being easily accessed. Single underscore could be treated as "protected".

Getter/Setter:

You can use these if you want to do more to wrap the process and 'protect' your 'private' attributes. But its, again, not required. You could also use Properties, which has getter/setter features.

jdi
  • 90,542
  • 19
  • 167
  • 203
0

1) http://docs.python.org/tutorial/classes.html#private-variables

“Private” instance variables that cannot be accessed except from inside an object don’t exist in Python. However, there is a convention that is followed by most Python code: 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.

(continue reading for more details about class-private variables and name mangling)

2) http://docs.python.org/library/functions.html#property

TML
  • 12,813
  • 3
  • 38
  • 45