0

I see that with help of underscore, one can declare private members in class but with one score, it is still accessed in main but with two it is not. If two makes the variable private then why there is single score one? What is the use/purpose of single underscore variable?

class Temp:
    def __init__(self):
    self.a = 123
    self._b = 123
    self.__c = 123

obj = Temp()
print(obj.a)
print(obj._b)
print(obj.__c)
desertnaut
  • 57,590
  • 26
  • 140
  • 166
  • Are you familiar with the [``public``, ``protected``, ``private`` distinction as used in Java, C++, C# and others](https://en.wikipedia.org/wiki/Access_modifiers#Names_of_keywords)? – MisterMiyagi Oct 08 '21 at 07:39
  • Yes @MisterMiyagi, I know the concept of encapsulation but I am not clear in python –  Oct 08 '21 at 07:46
  • Well, roughly ``a`` is public, *``_a`` is protected* and ``__a`` is private. Since Python classes are… different things than C++/C#/... classes, it's not enforced, though. – MisterMiyagi Oct 08 '21 at 07:47
  • 1
    @MisterMiyagi _protected_ is not really a thing in Python. – Matthias Oct 08 '21 at 08:32
  • @Matthias Neither are the rest. It seems like a close enough analogy for explanation, though. – MisterMiyagi Oct 08 '21 at 08:49
  • Welcome to SO; question has nothing to do with `machine-learning`, kindly do not spam irrelevant tags (removed). – desertnaut Oct 08 '21 at 09:04

2 Answers2

5

Here's why that's the "standard," a little different from other languages.

  1. No underscore indicates it's a public thing that users of that class can touch/modify/use
  2. One underscore is more of an implementation detail that usually (note the term usually) should only be referenced/used in sub-classes or if you know what you're doing. The beautiful thing about python is that we're all adults here and if someone wants to access something for some really custom thing then they should be able to.
  3. Two underscores is name mangled to include the classname like so _Temp__c behind the scenes to prevent your variables clashing with a subclass. However, I would stay away from defaulting to two because it's not a great habit and is generally unnecessary. There are arguments and other posts about it that you can read up on like this

Note: there is no difference to variables/methods that either have an underscore or not. It's just a convention for classes that's not enforced but rather accepted by the community to be private.
Note #2: There is an exception described by Matthias for non-class methods

smerkd
  • 476
  • 3
  • 8
  • A double leading underscore isn't used to make something (super-)private. It's to prevent name clashes when subclassing. – Matthias Oct 08 '21 at 08:18
  • That's true, I assumed it would be easier to understand as something "super" private instead of going too deep into name-clashing (as I hinted with the mangling). I'll just remove that part. – smerkd Oct 08 '21 at 08:34
  • 1
    "There is no difference" is not quite right. One shouldn't use wildcard imports, but it's done nevertheless and `from foo import *` does not import objects whose names start with an underscore. Of course this only applies to objects on top-level, not attributes and methods of a class. – Matthias Oct 08 '21 at 11:26
  • 1
    To be more specific, name mangling only occurs if the name starts with two underscores and ends with zero or one underscores. – sj95126 Oct 08 '21 at 14:25
  • @Matthias I didn't even know that rule. I oddly never do that or came across that, mainly since I don't wildcard. – smerkd Oct 08 '21 at 17:08
  • @smerkd This mechanism is wildly unknown. I forgot it too and found it while I was doing research for my comment. – Matthias Oct 10 '21 at 17:57
2

In Python, there is no existence of “private” instance variables that cannot be accessed except inside an object.
However, a convention is being followed by most Python code and coders i.e., a name prefixed with an underscore, For e.g. _xyz should be treated as a non-public part of the API or any Python code, whether it is a function, a method, or a data member

balderman
  • 22,927
  • 7
  • 34
  • 52
  • Can you give me some example? that can help in clarify –  Oct 08 '21 at 07:46
  • @Ammar Look at the official [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/#method-names-and-instance-variables). Cite 1: "Use one leading underscore only for non-public methods and instance variables.". Cite 2: "To avoid name clashes with subclasses, use two leading underscores to invoke Python's name mangling rules." – Matthias Oct 08 '21 at 08:23