What's the difference between _b and b in this place - python

class a:
def __init__(self):
self._b()#why here use _b,not b,What's the difference
self._c='cccc'#why here use _c,not c,What's the difference
def _b():
print 'bbbb'
a.py
class a:
def __init__(self):
self._b()#why here use _b,not b,What's the difference
self._c='cccc'#why here use _c,not c,What's the difference
def _b(self):
print 'bbbb'
b.py
from a import *
b=a()
b._b()
print b._c
it print
bbbb
bbbb
bbbb
bbbb
cccc
Why can print out these, aren't _b and _c private variables.

Prefixing a variable or function name with an underscore is a convention in Python to indicate that the variable is private. From the docs:
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.

Per pep8 (http://www.python.org/dev/peps/pep-0008/), a single underscore is intended to denote a "generally private" method or attribute. The interpreter itself has no interaction with the single underscore, its more of a convention. The double underscore OTOH has significance within the interpreter.

Basically, the idea is that in Python convention, there are three levels of encapsulation/hiding.
Public attributes and methods: These are meant to be accessed by other classes without restriction.
Private attributes and methods (prefixed with an underscore): These are meant to be hidden from the outside world. The underscore serves as something like a warning to say: you shouldn't be touching this method unless you really know what you're doing. Primarily, this is used to differentiate between end users (the lesser mortals) and other developers.
There is a third level called mangled. Any attributes/methods that are mangled are basically not to be touched by anyone who is not the author of that code. It is important to the core functioning of the program and should not be touched, because if it is misused, then it may lead to unwanted/unplanned behavior.
In your case, the '_b' method is a private method. The author of this code wants to let you know that this is not meant for public use, rather if you are writing a wrapper around this class or something of that nature (basically if you are developer using this class), then you may use that method. Otherwise, it is better that you don't.
Also, a single underscore in front of a variable(or method) ties it to that class. So when a._b is called, the interpreter looks for it in the definition of the class a.

Difference between single and double underscore:
class Foo(object):
def regular_method(self):
print 'ok'
def _soft_private(self):
print 'ok'
def __mangled_private(self):
print 'ok'
f = Foo()
f.regular_method()
# prints ok
f._soft_private()
# print ok
f.__mangled_private()
# error! no such attribute. BUT:
f._Foo__mangled_private()
# prints ok
So in essence there is no real "privacy" in python, but convention of using single underscore to warn developer using your API that he's doing so at his own risk.

You'll notice that b isn't defined anywhere. While _b is.
Unless you're asking why that naming convention is being used, in which case, you should ask the author of that code.

The underscore is simply used to denote that the variable is private.

The class object a has an attribute _b which is found when asking for self._b. The same class object a has no attribute b.
_b and b are as different as beehive and zulu.
You will get a parameter error when calling self._b because Python will implicitly pass self as the first argument to a bound method. The signature should be:
def _b(self):
print('bbbb')

Related

Code works in debug console, but raises NameError in debug or normal execution [duplicate]

What do single and double leading underscores before an object's name represent in Python?
Single Underscore
In a class, names with a leading underscore indicate to other programmers that the attribute or method is intended to be be used inside that class. However, privacy is not enforced in any way.
Using leading underscores for functions in a module indicates it should not be imported from somewhere else.
From the PEP-8 style guide:
_single_leading_underscore: weak "internal use" indicator. E.g. from M import * does not import objects whose name starts with an underscore.
Double Underscore (Name Mangling)
From the Python docs:
Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped. This mangling is done without regard to the syntactic position of the identifier, so it can be used to define class-private instance and class variables, methods, variables stored in globals, and even variables stored in instances. private to this class on instances of other classes.
And a warning from the same page:
Name mangling is intended to give classes an easy way to define “private” instance variables and methods, without having to worry about instance variables defined by derived classes, or mucking with instance variables by code outside the class. Note that the mangling rules are designed mostly to avoid accidents; it still is possible for a determined soul to access or modify a variable that is considered private.
Example
>>> class MyClass():
... def __init__(self):
... self.__superprivate = "Hello"
... self._semiprivate = ", world!"
...
>>> mc = MyClass()
>>> print mc.__superprivate
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: myClass instance has no attribute '__superprivate'
>>> print mc._semiprivate
, world!
>>> print mc.__dict__
{'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}
_foo: Only a convention. A way for the programmer to indicate that the variable is private (whatever that means in Python).
__foo: This has real meaning. The interpreter replaces this name with _classname__foo as a way to ensure that the name will not overlap with a similar name in another class.
__foo__: Only a convention. A way for the Python system to use names that won't conflict with user names.
No other form of underscores have meaning in the Python world. Also, there's no difference between class, variable, global, etc in these conventions.
Excellent answers so far but some tidbits are missing. A single leading underscore isn't exactly just a convention: if you use from foobar import *, and module foobar does not define an __all__ list, the names imported from the module do not include those with a leading underscore. Let's say it's mostly a convention, since this case is a pretty obscure corner;-).
The leading-underscore convention is widely used not just for private names, but also for what C++ would call protected ones -- for example, names of methods that are fully intended to be overridden by subclasses (even ones that have to be overridden since in the base class they raise NotImplementedError!-) are often single-leading-underscore names to indicate to code using instances of that class (or subclasses) that said methods are not meant to be called directly.
For example, to make a thread-safe queue with a different queueing discipline than FIFO, one imports Queue, subclasses Queue.Queue, and overrides such methods as _get and _put; "client code" never calls those ("hook") methods, but rather the ("organizing") public methods such as put and get (this is known as the Template Method design pattern -- see e.g. here for an interesting presentation based on a video of a talk of mine on the subject, with the addition of synopses of the transcript).
Edit: The video links in the description of the talks are now broken. You can find the first two videos here and here.
._variable is semiprivate and meant just for convention
.__variable is often incorrectly considered superprivate, while it's actual meaning is just to namemangle to prevent accidental access[1]
.__variable__ is typically reserved for builtin methods or variables
You can still access .__mangled variables if you desperately want to. The double underscores just namemangles, or renames, the variable to something like instance._className__mangled
Example:
class Test(object):
def __init__(self):
self.__a = 'a'
self._b = 'b'
>>> t = Test()
>>> t._b
'b'
t._b is accessible because it is only hidden by convention
>>> t.__a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Test' object has no attribute '__a'
t.__a isn't found because it no longer exists due to namemangling
>>> t._Test__a
'a'
By accessing instance._className__variable instead of just the double underscore name, you can access the hidden value
Single underscore at the beginning:
Python doesn't have real private methods. Instead, one underscore at the start of a method or attribute name means you shouldn't access this method, because it's not part of the API.
class BaseForm(StrAndUnicode):
def _get_errors(self):
"Returns an ErrorDict for the data provided for the form"
if self._errors is None:
self.full_clean()
return self._errors
errors = property(_get_errors)
(This code snippet was taken from django source code: django/forms/forms.py). In this code, errors is a public property, but the method this property calls, _get_errors, is "private", so you shouldn't access it.
Two underscores at the beginning:
This causes a lot of confusion. It should not be used to create a private method. It should be used to avoid your method being overridden by a subclass or accessed accidentally. Let's see an example:
class A(object):
def __test(self):
print "I'm a test method in class A"
def test(self):
self.__test()
a = A()
a.test()
# a.__test() # This fails with an AttributeError
a._A__test() # Works! We can access the mangled name directly!
Output:
$ python test.py
I'm test method in class A
I'm test method in class A
Now create a subclass B and do customization for __test method
class B(A):
def __test(self):
print "I'm test method in class B"
b = B()
b.test()
Output will be....
$ python test.py
I'm test method in class A
As we have seen, B.test() didn't call B.__test() methods, as we might expect. But in fact, this is the correct behavior for __. The two methods called __test() are automatically renamed (mangled) to _A__test() and _B__test(), so they do not accidentally override. When you create a method starting with __ it means that you don't want to anyone to be able to override it, and you only intend to access it from inside its own class.
Two underscores at the beginning and at the end:
When we see a method like __this__, don't call it. This is a method which python is meant to call, not you. Let's take a look:
>>> name = "test string"
>>> name.__len__()
11
>>> len(name)
11
>>> number = 10
>>> number.__add__(40)
50
>>> number + 50
60
There is always an operator or native function which calls these magic methods. Sometimes it's just a hook python calls in specific situations. For example __init__() is called when the object is created after __new__() is called to build the instance...
Let's take an example...
class FalseCalculator(object):
def __init__(self, number):
self.number = number
def __add__(self, number):
return self.number - number
def __sub__(self, number):
return self.number + number
number = FalseCalculator(20)
print number + 10 # 10
print number - 20 # 40
For more details, see the [PEP-8 guide][1]. For more magic methods, see [this PDF][2].
[1]: https://www.python.org/dev/peps/pep-0008/#method-names-and-instance-variables
[2]://github.com/RafeKettler/magicmethods/blob/master/magicmethods.pdf
According to Meaning of Underscores in Python
Single Leading Underscore(_var): Naming convention indicating a name is meant for internal use. Generally not enforced by the Python interpreter (except in wildcard imports) and meant as a hint to the programmer only.
Single Trailing Underscore(var_): Used by convention to avoid naming conflicts with Python keywords.
Double Leading Underscore(__var): Triggers name mangling when used in a class context. Enforced by the Python interpreter.
Double Leading and Trailing Underscore(__var__): Indicates special methods defined by the Python language. Avoid this naming scheme for your own attributes.
Single Underscore(_): Sometimes used as a name for temporary or insignificant variables (“don’t care”). Also: The result of the last expression in a Python REPL.
Sometimes you have what appears to be a tuple with a leading underscore as in
def foo(bar):
return _('my_' + bar)
In this case, what's going on is that _() is an alias for a localization function that operates on text to put it into the proper language, etc. based on the locale. For example, Sphinx does this, and you'll find among the imports
from sphinx.locale import l_, _
and in sphinx.locale, _() is assigned as an alias of some localization function.
Since so many people are referring to Raymond's talk, I'll just make it a little easier by writing down what he said:
The intention of the double underscores was not about privacy. The intention was to use it exactly like this
class Circle(object):
def __init__(self, radius):
self.radius = radius
def area(self):
p = self.__perimeter()
r = p / math.pi / 2.0
return math.pi * r ** 2.0
def perimeter(self):
return 2.0 * math.pi * self.radius
__perimeter = perimeter # local reference
class Tire(Circle):
def perimeter(self):
return Circle.perimeter(self) * 1.25
It's actually the opposite of privacy, it's all about freedom. It makes your subclasses free to override any one method without breaking the others.
Say you don't keep a local reference of perimeter in Circle. Now, a derived class Tire overrides the implementation of perimeter, without touching area. When you call Tire(5).area(), in theory it should still be using Circle.perimeter for computation, but in reality it's using Tire.perimeter, which is not the intended behavior. That's why we need a local reference in Circle.
But why __perimeter instead of _perimeter? Because _perimeter still gives derived class the chance to override:
class Tire(Circle):
def perimeter(self):
return Circle.perimeter(self) * 1.25
_perimeter = perimeter
Double underscores has name mangling, so there's a very little chance that the local reference in parent class get override in derived class. thus "makes your subclasses free to override any one method without breaking the others".
If your class won't be inherited, or method overriding does not break anything, then you simply don't need __double_leading_underscore.
_var: variables with a leading single underscore in python are classic variables, intended to inform others using your code that this variable should be reserved for internal use. They differ on one point from classic variables: they are not imported when doing a wildcard import of an object/module where they are defined (exceptions when defining the __all__ variable). Eg:
# foo.py
var = "var"
_var = "_var"
# bar.py
from foo import *
print(dir()) # list of defined objects, contains 'var' but not '_var'
print(var) # var
print(_var) # NameError: name '_var' is not defined
_ : the single underscore is a special case of the leading single underscore variables. It is used by convention as a trash variable, to store a value that is not intended to be later accessed. It is also not imported by wildcard imports. Eg: this for loop prints "I must not talk in class" 10 times, and never needs to access the _ variable.
for _ in range(10):
print("I must not talk in class")
var_: single trailing underscore variables. They are classic variables used by convention to avoid conflicts with Python keyword. Eg:
class_ = "MyClassName"
__var: double leading underscore variables (at least two leading underscores, at most one trailing underscore). When used as class attributes (variables and methods), these variables are subject to name mangling: outside of the class, python will rename the attribute to _<Class_name>__<attribute_name>. Example:
class MyClass:
__an_attribute = "attribute_value"
my_class = MyClass()
print(my_class._MyClass__an_attribute) # "attribute_value"
print(my_class.__an_attribute) # AttributeError: 'MyClass' object has no attribute '__an_attribute'
When used as variables outside a class, they behave like single leading underscore variables.
__var__: double leading and trailing underscore variables (at least two leading and trailing underscores). Also called dunders. This naming convention is used by python to define variables internally. Avoid using this convention to prevent name conflicts that could arise with python updates. Dunder variables behave like single leading underscore variables: they are not subject to name mangling when used inside classes, but are not imported in wildcard imports.
If one really wants to make a variable read-only, IMHO the best way would be to use property() with only getter passed to it. With property() we can have complete control over the data.
class PrivateVarC(object):
def get_x(self):
pass
def set_x(self, val):
pass
rwvar = property(get_p, set_p)
ronly = property(get_p)
I understand that OP asked a little different question but since I found another question asking for 'how to set private variables' marked duplicate with this one, I thought of adding this additional info here.
Great answers and all are correct.I have provided simple example along with simple definition/meaning.
Meaning:
some_variable --► it's public anyone can see this.
_some_variable --► it's public anyone can see this but it's a convention to indicate private...warning no enforcement is done by Python.
__some_varaible --► Python replaces the variable name with _classname__some_varaible (AKA name mangling) and it reduces/hides it's visibility and be more like private variable.
Just to be honest here According to Python documentation
"“Private” instance variables that cannot be accessed except from
inside an object don’t exist in Python"
The example:
class A():
here="abc"
_here="_abc"
__here="__abc"
aObject=A()
print(aObject.here)
print(aObject._here)
# now if we try to print __here then it will fail because it's not public variable
#print(aObject.__here)
Here is a simple illustrative example on how double underscore properties can affect an inherited class. So with the following setup:
class parent(object):
__default = "parent"
def __init__(self, name=None):
self.default = name or self.__default
#property
def default(self):
return self.__default
#default.setter
def default(self, value):
self.__default = value
class child(parent):
__default = "child"
if you then create a child instance in the python REPL, you will see the below
child_a = child()
child_a.default # 'parent'
child_a._child__default # 'child'
child_a._parent__default # 'parent'
child_b = child("orphan")
## this will show
child_b.default # 'orphan'
child_a._child__default # 'child'
child_a._parent__default # 'orphan'
This may be obvious to some, but it caught me off guard in a much more complex environment
Single leading underscores is a convention. there is no difference from the interpreter's point of view if whether names starts with a single underscore or not.
Double leading and trailing underscores are used for built-in methods, such as __init__, __bool__, etc.
Double leading underscores w/o trailing counterparts are a convention too, however, the class methods will be mangled by the interpreter. For variables or basic function names no difference exists.
Your question is good, it is not only about methods. Functions and objects in modules are commonly prefixed with one underscore as well, and can be prefixed by two.
But __double_underscore names are not name-mangled in modules, for example. What happens is that names beginning with one (or more) underscores are not imported if you import all from a module (from module import *), nor are the names shown in help(module).
“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.
reference
https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references
Getting the facts of _ and __ is pretty easy; the other answers express them pretty well. The usage is much harder to determine.
This is how I see it:
_
Should be used to indicate that a function is not for public use as for example an API. This and the import restriction make it behave much like internal in c#.
__
Should be used to avoid name collision in the inheritace hirarchy and to avoid latebinding. Much like private in c#.
==>
If you want to indicate that something is not for public use, but it should act like protected use _.
If you want to indicate that something is not for public use, but it should act like private use __.
This is also a quote that I like very much:
The problem is that the author of a class may legitimately think "this
attribute/method name should be private, only accessible from within
this class definition" and use the __private convention. But later on,
a user of that class may make a subclass that legitimately needs
access to that name. So either the superclass has to be modified
(which may be difficult or impossible), or the subclass code has to
use manually mangled names (which is ugly and fragile at best).
But the problem with that is in my opinion that if there's no IDE that warns you when you override methods, finding the error might take you a while if you have accidentially overriden a method from a base-class.
In the case of methods, you can use the double underscore to hide away private 'methods' with the following pattern:
# Private methods of MyClass
def _MyClass__do_something(obj:'MyClass'):
print('_MyClass__do_something() called. type(obj) = {}'.format(type(obj)))
class MyClass():
def __init__(self):
__do_something(self)
mc = MyClass()
Output:
_MyClass__do_something() called. type(obj) = <class '__main__.MyClass'>
I stumbled across this today when I tried using double underscore for class methods and got the NameError: name '_<class><method>' is not defined error.
To frame it in simple words, let us compare python's variables' accessibility conventions to access modifiers in Java:
(Python) = (Java)
_single_underscore_variable = Protected (Accessible to class and its subclasses)
__double_underscore_variable = Private (Accessible to class itself only)
no_underscore_variable = Public (Accessible anywhere)
Reference: https://www.tutorialsteacher.com/python/public-private-protected-modifiers

Why does overriding a function that refers to a double-underscore variable not change that variable from a parent's function's view? [duplicate]

What do single and double leading underscores before an object's name represent in Python?
Single Underscore
In a class, names with a leading underscore indicate to other programmers that the attribute or method is intended to be be used inside that class. However, privacy is not enforced in any way.
Using leading underscores for functions in a module indicates it should not be imported from somewhere else.
From the PEP-8 style guide:
_single_leading_underscore: weak "internal use" indicator. E.g. from M import * does not import objects whose name starts with an underscore.
Double Underscore (Name Mangling)
From the Python docs:
Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped. This mangling is done without regard to the syntactic position of the identifier, so it can be used to define class-private instance and class variables, methods, variables stored in globals, and even variables stored in instances. private to this class on instances of other classes.
And a warning from the same page:
Name mangling is intended to give classes an easy way to define “private” instance variables and methods, without having to worry about instance variables defined by derived classes, or mucking with instance variables by code outside the class. Note that the mangling rules are designed mostly to avoid accidents; it still is possible for a determined soul to access or modify a variable that is considered private.
Example
>>> class MyClass():
... def __init__(self):
... self.__superprivate = "Hello"
... self._semiprivate = ", world!"
...
>>> mc = MyClass()
>>> print mc.__superprivate
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: myClass instance has no attribute '__superprivate'
>>> print mc._semiprivate
, world!
>>> print mc.__dict__
{'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}
_foo: Only a convention. A way for the programmer to indicate that the variable is private (whatever that means in Python).
__foo: This has real meaning. The interpreter replaces this name with _classname__foo as a way to ensure that the name will not overlap with a similar name in another class.
__foo__: Only a convention. A way for the Python system to use names that won't conflict with user names.
No other form of underscores have meaning in the Python world. Also, there's no difference between class, variable, global, etc in these conventions.
Excellent answers so far but some tidbits are missing. A single leading underscore isn't exactly just a convention: if you use from foobar import *, and module foobar does not define an __all__ list, the names imported from the module do not include those with a leading underscore. Let's say it's mostly a convention, since this case is a pretty obscure corner;-).
The leading-underscore convention is widely used not just for private names, but also for what C++ would call protected ones -- for example, names of methods that are fully intended to be overridden by subclasses (even ones that have to be overridden since in the base class they raise NotImplementedError!-) are often single-leading-underscore names to indicate to code using instances of that class (or subclasses) that said methods are not meant to be called directly.
For example, to make a thread-safe queue with a different queueing discipline than FIFO, one imports Queue, subclasses Queue.Queue, and overrides such methods as _get and _put; "client code" never calls those ("hook") methods, but rather the ("organizing") public methods such as put and get (this is known as the Template Method design pattern -- see e.g. here for an interesting presentation based on a video of a talk of mine on the subject, with the addition of synopses of the transcript).
Edit: The video links in the description of the talks are now broken. You can find the first two videos here and here.
._variable is semiprivate and meant just for convention
.__variable is often incorrectly considered superprivate, while it's actual meaning is just to namemangle to prevent accidental access[1]
.__variable__ is typically reserved for builtin methods or variables
You can still access .__mangled variables if you desperately want to. The double underscores just namemangles, or renames, the variable to something like instance._className__mangled
Example:
class Test(object):
def __init__(self):
self.__a = 'a'
self._b = 'b'
>>> t = Test()
>>> t._b
'b'
t._b is accessible because it is only hidden by convention
>>> t.__a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Test' object has no attribute '__a'
t.__a isn't found because it no longer exists due to namemangling
>>> t._Test__a
'a'
By accessing instance._className__variable instead of just the double underscore name, you can access the hidden value
Single underscore at the beginning:
Python doesn't have real private methods. Instead, one underscore at the start of a method or attribute name means you shouldn't access this method, because it's not part of the API.
class BaseForm(StrAndUnicode):
def _get_errors(self):
"Returns an ErrorDict for the data provided for the form"
if self._errors is None:
self.full_clean()
return self._errors
errors = property(_get_errors)
(This code snippet was taken from django source code: django/forms/forms.py). In this code, errors is a public property, but the method this property calls, _get_errors, is "private", so you shouldn't access it.
Two underscores at the beginning:
This causes a lot of confusion. It should not be used to create a private method. It should be used to avoid your method being overridden by a subclass or accessed accidentally. Let's see an example:
class A(object):
def __test(self):
print "I'm a test method in class A"
def test(self):
self.__test()
a = A()
a.test()
# a.__test() # This fails with an AttributeError
a._A__test() # Works! We can access the mangled name directly!
Output:
$ python test.py
I'm test method in class A
I'm test method in class A
Now create a subclass B and do customization for __test method
class B(A):
def __test(self):
print "I'm test method in class B"
b = B()
b.test()
Output will be....
$ python test.py
I'm test method in class A
As we have seen, B.test() didn't call B.__test() methods, as we might expect. But in fact, this is the correct behavior for __. The two methods called __test() are automatically renamed (mangled) to _A__test() and _B__test(), so they do not accidentally override. When you create a method starting with __ it means that you don't want to anyone to be able to override it, and you only intend to access it from inside its own class.
Two underscores at the beginning and at the end:
When we see a method like __this__, don't call it. This is a method which python is meant to call, not you. Let's take a look:
>>> name = "test string"
>>> name.__len__()
11
>>> len(name)
11
>>> number = 10
>>> number.__add__(40)
50
>>> number + 50
60
There is always an operator or native function which calls these magic methods. Sometimes it's just a hook python calls in specific situations. For example __init__() is called when the object is created after __new__() is called to build the instance...
Let's take an example...
class FalseCalculator(object):
def __init__(self, number):
self.number = number
def __add__(self, number):
return self.number - number
def __sub__(self, number):
return self.number + number
number = FalseCalculator(20)
print number + 10 # 10
print number - 20 # 40
For more details, see the [PEP-8 guide][1]. For more magic methods, see [this PDF][2].
[1]: https://www.python.org/dev/peps/pep-0008/#method-names-and-instance-variables
[2]://github.com/RafeKettler/magicmethods/blob/master/magicmethods.pdf
According to Meaning of Underscores in Python
Single Leading Underscore(_var): Naming convention indicating a name is meant for internal use. Generally not enforced by the Python interpreter (except in wildcard imports) and meant as a hint to the programmer only.
Single Trailing Underscore(var_): Used by convention to avoid naming conflicts with Python keywords.
Double Leading Underscore(__var): Triggers name mangling when used in a class context. Enforced by the Python interpreter.
Double Leading and Trailing Underscore(__var__): Indicates special methods defined by the Python language. Avoid this naming scheme for your own attributes.
Single Underscore(_): Sometimes used as a name for temporary or insignificant variables (“don’t care”). Also: The result of the last expression in a Python REPL.
Sometimes you have what appears to be a tuple with a leading underscore as in
def foo(bar):
return _('my_' + bar)
In this case, what's going on is that _() is an alias for a localization function that operates on text to put it into the proper language, etc. based on the locale. For example, Sphinx does this, and you'll find among the imports
from sphinx.locale import l_, _
and in sphinx.locale, _() is assigned as an alias of some localization function.
Since so many people are referring to Raymond's talk, I'll just make it a little easier by writing down what he said:
The intention of the double underscores was not about privacy. The intention was to use it exactly like this
class Circle(object):
def __init__(self, radius):
self.radius = radius
def area(self):
p = self.__perimeter()
r = p / math.pi / 2.0
return math.pi * r ** 2.0
def perimeter(self):
return 2.0 * math.pi * self.radius
__perimeter = perimeter # local reference
class Tire(Circle):
def perimeter(self):
return Circle.perimeter(self) * 1.25
It's actually the opposite of privacy, it's all about freedom. It makes your subclasses free to override any one method without breaking the others.
Say you don't keep a local reference of perimeter in Circle. Now, a derived class Tire overrides the implementation of perimeter, without touching area. When you call Tire(5).area(), in theory it should still be using Circle.perimeter for computation, but in reality it's using Tire.perimeter, which is not the intended behavior. That's why we need a local reference in Circle.
But why __perimeter instead of _perimeter? Because _perimeter still gives derived class the chance to override:
class Tire(Circle):
def perimeter(self):
return Circle.perimeter(self) * 1.25
_perimeter = perimeter
Double underscores has name mangling, so there's a very little chance that the local reference in parent class get override in derived class. thus "makes your subclasses free to override any one method without breaking the others".
If your class won't be inherited, or method overriding does not break anything, then you simply don't need __double_leading_underscore.
_var: variables with a leading single underscore in python are classic variables, intended to inform others using your code that this variable should be reserved for internal use. They differ on one point from classic variables: they are not imported when doing a wildcard import of an object/module where they are defined (exceptions when defining the __all__ variable). Eg:
# foo.py
var = "var"
_var = "_var"
# bar.py
from foo import *
print(dir()) # list of defined objects, contains 'var' but not '_var'
print(var) # var
print(_var) # NameError: name '_var' is not defined
_ : the single underscore is a special case of the leading single underscore variables. It is used by convention as a trash variable, to store a value that is not intended to be later accessed. It is also not imported by wildcard imports. Eg: this for loop prints "I must not talk in class" 10 times, and never needs to access the _ variable.
for _ in range(10):
print("I must not talk in class")
var_: single trailing underscore variables. They are classic variables used by convention to avoid conflicts with Python keyword. Eg:
class_ = "MyClassName"
__var: double leading underscore variables (at least two leading underscores, at most one trailing underscore). When used as class attributes (variables and methods), these variables are subject to name mangling: outside of the class, python will rename the attribute to _<Class_name>__<attribute_name>. Example:
class MyClass:
__an_attribute = "attribute_value"
my_class = MyClass()
print(my_class._MyClass__an_attribute) # "attribute_value"
print(my_class.__an_attribute) # AttributeError: 'MyClass' object has no attribute '__an_attribute'
When used as variables outside a class, they behave like single leading underscore variables.
__var__: double leading and trailing underscore variables (at least two leading and trailing underscores). Also called dunders. This naming convention is used by python to define variables internally. Avoid using this convention to prevent name conflicts that could arise with python updates. Dunder variables behave like single leading underscore variables: they are not subject to name mangling when used inside classes, but are not imported in wildcard imports.
If one really wants to make a variable read-only, IMHO the best way would be to use property() with only getter passed to it. With property() we can have complete control over the data.
class PrivateVarC(object):
def get_x(self):
pass
def set_x(self, val):
pass
rwvar = property(get_p, set_p)
ronly = property(get_p)
I understand that OP asked a little different question but since I found another question asking for 'how to set private variables' marked duplicate with this one, I thought of adding this additional info here.
Great answers and all are correct.I have provided simple example along with simple definition/meaning.
Meaning:
some_variable --► it's public anyone can see this.
_some_variable --► it's public anyone can see this but it's a convention to indicate private...warning no enforcement is done by Python.
__some_varaible --► Python replaces the variable name with _classname__some_varaible (AKA name mangling) and it reduces/hides it's visibility and be more like private variable.
Just to be honest here According to Python documentation
"“Private” instance variables that cannot be accessed except from
inside an object don’t exist in Python"
The example:
class A():
here="abc"
_here="_abc"
__here="__abc"
aObject=A()
print(aObject.here)
print(aObject._here)
# now if we try to print __here then it will fail because it's not public variable
#print(aObject.__here)
Here is a simple illustrative example on how double underscore properties can affect an inherited class. So with the following setup:
class parent(object):
__default = "parent"
def __init__(self, name=None):
self.default = name or self.__default
#property
def default(self):
return self.__default
#default.setter
def default(self, value):
self.__default = value
class child(parent):
__default = "child"
if you then create a child instance in the python REPL, you will see the below
child_a = child()
child_a.default # 'parent'
child_a._child__default # 'child'
child_a._parent__default # 'parent'
child_b = child("orphan")
## this will show
child_b.default # 'orphan'
child_a._child__default # 'child'
child_a._parent__default # 'orphan'
This may be obvious to some, but it caught me off guard in a much more complex environment
Single leading underscores is a convention. there is no difference from the interpreter's point of view if whether names starts with a single underscore or not.
Double leading and trailing underscores are used for built-in methods, such as __init__, __bool__, etc.
Double leading underscores w/o trailing counterparts are a convention too, however, the class methods will be mangled by the interpreter. For variables or basic function names no difference exists.
Your question is good, it is not only about methods. Functions and objects in modules are commonly prefixed with one underscore as well, and can be prefixed by two.
But __double_underscore names are not name-mangled in modules, for example. What happens is that names beginning with one (or more) underscores are not imported if you import all from a module (from module import *), nor are the names shown in help(module).
“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.
reference
https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references
Getting the facts of _ and __ is pretty easy; the other answers express them pretty well. The usage is much harder to determine.
This is how I see it:
_
Should be used to indicate that a function is not for public use as for example an API. This and the import restriction make it behave much like internal in c#.
__
Should be used to avoid name collision in the inheritace hirarchy and to avoid latebinding. Much like private in c#.
==>
If you want to indicate that something is not for public use, but it should act like protected use _.
If you want to indicate that something is not for public use, but it should act like private use __.
This is also a quote that I like very much:
The problem is that the author of a class may legitimately think "this
attribute/method name should be private, only accessible from within
this class definition" and use the __private convention. But later on,
a user of that class may make a subclass that legitimately needs
access to that name. So either the superclass has to be modified
(which may be difficult or impossible), or the subclass code has to
use manually mangled names (which is ugly and fragile at best).
But the problem with that is in my opinion that if there's no IDE that warns you when you override methods, finding the error might take you a while if you have accidentially overriden a method from a base-class.
In the case of methods, you can use the double underscore to hide away private 'methods' with the following pattern:
# Private methods of MyClass
def _MyClass__do_something(obj:'MyClass'):
print('_MyClass__do_something() called. type(obj) = {}'.format(type(obj)))
class MyClass():
def __init__(self):
__do_something(self)
mc = MyClass()
Output:
_MyClass__do_something() called. type(obj) = <class '__main__.MyClass'>
I stumbled across this today when I tried using double underscore for class methods and got the NameError: name '_<class><method>' is not defined error.
To frame it in simple words, let us compare python's variables' accessibility conventions to access modifiers in Java:
(Python) = (Java)
_single_underscore_variable = Protected (Accessible to class and its subclasses)
__double_underscore_variable = Private (Accessible to class itself only)
no_underscore_variable = Public (Accessible anywhere)
Reference: https://www.tutorialsteacher.com/python/public-private-protected-modifiers

single underscore vs double underscore encapsulation in python

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)
Here's why that's the "standard," a little different from other languages.
No underscore indicates it's a public thing that users of that class can touch/modify/use
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.
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
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

Why is changing class variables considered a bad practice? [duplicate]

I would like to have a function in my class, which I am going to use only inside methods of this class. I will not call it outside the implementations of these methods. In C++, I would use a method declared in the private section of the class. What is the best way to implement such a function in Python?
I am thinking of using a static decorator for this case. Can I use a function without any decorators and the self word?
Python doesn't have the concept of private methods or attributes. It's all about how you implement your class. But you can use pseudo-private variables (name mangling); any variable preceded by __(two underscores) becomes a pseudo-private variable.
From the documentation:
Since there is a valid use-case for class-private members (namely to
avoid name clashes of names with names defined by subclasses), there
is limited support for such a mechanism, called name mangling. Any
identifier of the form __spam (at least two leading underscores, at
most one trailing underscore) is textually replaced with
_classname__spam, where classname is the current class name with leading underscore(s) stripped. This mangling is done without regard
to the syntactic position of the identifier, as long as it occurs
within the definition of a class.
class A:
def __private(self):
pass
So __private now actually becomes _A__private.
Example of a static method:
>>> class A:
... #staticmethod # Not required in Python 3.x
... def __private():
... print 'hello'
...
>>> A._A__private()
hello
Python doesn't have the concept of 'private' the way many other languages do. It is built on the consenting adult principle that says that users of your code will use it responsibly. By convention, attributes starting with a single or double leading underscore will be treated as part of the internal implementation, but they are not actually hidden from users. Double underscore will cause name mangling of the attribute name though.
Also, note that self is only special by convention, not by any feature of the language. Instance methods, when called as members of an instance, are implicitly passed the instance as a first argument, but in the implementation of the method itself, that argument can technically be named any arbitrary thing you want. self is just the convention for ease of understanding code. As a result, not including self in the signature of a method has no actual functional effect other than causing the implicit instance argument to be assigned to the next variable name in the signature.
This is of course different for class methods, which receive the instance of the class object itself as an implicit first argument, and static methods, which receive no implicit arguments at all.
Python just doesn't do private. If you like you can follow convention and precede the name with a single underscore, but it's up to other coders to respect that in a gentlemanly† fashion
† or gentlewomanly
There is plenty of great stuff here with obfuscation using leading underscores. Personally, I benefit greatly from the language design decision to make everything public as it reduces the time it takes to understand and use new modules.
However, if you're determined to implement private attributes/methods and you're willing to be unpythonic, you could do something along the lines of:
from pprint import pprint
# CamelCase because it 'acts' like a class
def SneakyCounter():
class SneakyCounterInternal(object):
def __init__(self):
self.counter = 0
def add_two(self):
self.increment()
self.increment()
def increment(self):
self.counter += 1
def reset(self):
print 'count prior to reset: {}'.format(self.counter)
self.counter = 0
sneaky_counter = SneakyCounterInternal()
class SneakyCounterExternal(object):
def add_two(self):
sneaky_counter.add_two()
def reset(self):
sneaky_counter.reset()
return SneakyCounterExternal()
# counter attribute is not accessible from out here
sneaky_counter = SneakyCounter()
sneaky_counter.add_two()
sneaky_counter.add_two()
sneaky_counter.reset()
# `increment` and `counter` not exposed (AFAIK)
pprint(dir(sneaky_counter))
It is hard to imagine a case where you'd want to do this, but it is possible.
You just don't do it:
The Pythonic way is to not document those methods/members using docstrings, only with "real" code comments. And the convention is to append a single or a double underscore to them;
Then you can use double underscores in front of your member, so they are made local to the class (it's mostly name mangling, i.e., the real name of the member outside of the class becomes: instance.__classname_membername). It's useful to avoid conflicts when using inheritance, or create a "private space" between children of a class.
As far as I can tell, it is possible to "hide" variables using metaclasses, but that violates the whole philosophy of Python, so I won't go into details about that.

What is special about __func__() functions in python 2.7 [duplicate]

What do single and double leading underscores before an object's name represent in Python?
Single Underscore
In a class, names with a leading underscore indicate to other programmers that the attribute or method is intended to be be used inside that class. However, privacy is not enforced in any way.
Using leading underscores for functions in a module indicates it should not be imported from somewhere else.
From the PEP-8 style guide:
_single_leading_underscore: weak "internal use" indicator. E.g. from M import * does not import objects whose name starts with an underscore.
Double Underscore (Name Mangling)
From the Python docs:
Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped. This mangling is done without regard to the syntactic position of the identifier, so it can be used to define class-private instance and class variables, methods, variables stored in globals, and even variables stored in instances. private to this class on instances of other classes.
And a warning from the same page:
Name mangling is intended to give classes an easy way to define “private” instance variables and methods, without having to worry about instance variables defined by derived classes, or mucking with instance variables by code outside the class. Note that the mangling rules are designed mostly to avoid accidents; it still is possible for a determined soul to access or modify a variable that is considered private.
Example
>>> class MyClass():
... def __init__(self):
... self.__superprivate = "Hello"
... self._semiprivate = ", world!"
...
>>> mc = MyClass()
>>> print mc.__superprivate
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: myClass instance has no attribute '__superprivate'
>>> print mc._semiprivate
, world!
>>> print mc.__dict__
{'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}
_foo: Only a convention. A way for the programmer to indicate that the variable is private (whatever that means in Python).
__foo: This has real meaning. The interpreter replaces this name with _classname__foo as a way to ensure that the name will not overlap with a similar name in another class.
__foo__: Only a convention. A way for the Python system to use names that won't conflict with user names.
No other form of underscores have meaning in the Python world. Also, there's no difference between class, variable, global, etc in these conventions.
Excellent answers so far but some tidbits are missing. A single leading underscore isn't exactly just a convention: if you use from foobar import *, and module foobar does not define an __all__ list, the names imported from the module do not include those with a leading underscore. Let's say it's mostly a convention, since this case is a pretty obscure corner;-).
The leading-underscore convention is widely used not just for private names, but also for what C++ would call protected ones -- for example, names of methods that are fully intended to be overridden by subclasses (even ones that have to be overridden since in the base class they raise NotImplementedError!-) are often single-leading-underscore names to indicate to code using instances of that class (or subclasses) that said methods are not meant to be called directly.
For example, to make a thread-safe queue with a different queueing discipline than FIFO, one imports Queue, subclasses Queue.Queue, and overrides such methods as _get and _put; "client code" never calls those ("hook") methods, but rather the ("organizing") public methods such as put and get (this is known as the Template Method design pattern -- see e.g. here for an interesting presentation based on a video of a talk of mine on the subject, with the addition of synopses of the transcript).
Edit: The video links in the description of the talks are now broken. You can find the first two videos here and here.
._variable is semiprivate and meant just for convention
.__variable is often incorrectly considered superprivate, while it's actual meaning is just to namemangle to prevent accidental access[1]
.__variable__ is typically reserved for builtin methods or variables
You can still access .__mangled variables if you desperately want to. The double underscores just namemangles, or renames, the variable to something like instance._className__mangled
Example:
class Test(object):
def __init__(self):
self.__a = 'a'
self._b = 'b'
>>> t = Test()
>>> t._b
'b'
t._b is accessible because it is only hidden by convention
>>> t.__a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Test' object has no attribute '__a'
t.__a isn't found because it no longer exists due to namemangling
>>> t._Test__a
'a'
By accessing instance._className__variable instead of just the double underscore name, you can access the hidden value
Single underscore at the beginning:
Python doesn't have real private methods. Instead, one underscore at the start of a method or attribute name means you shouldn't access this method, because it's not part of the API.
class BaseForm(StrAndUnicode):
def _get_errors(self):
"Returns an ErrorDict for the data provided for the form"
if self._errors is None:
self.full_clean()
return self._errors
errors = property(_get_errors)
(This code snippet was taken from django source code: django/forms/forms.py). In this code, errors is a public property, but the method this property calls, _get_errors, is "private", so you shouldn't access it.
Two underscores at the beginning:
This causes a lot of confusion. It should not be used to create a private method. It should be used to avoid your method being overridden by a subclass or accessed accidentally. Let's see an example:
class A(object):
def __test(self):
print "I'm a test method in class A"
def test(self):
self.__test()
a = A()
a.test()
# a.__test() # This fails with an AttributeError
a._A__test() # Works! We can access the mangled name directly!
Output:
$ python test.py
I'm test method in class A
I'm test method in class A
Now create a subclass B and do customization for __test method
class B(A):
def __test(self):
print "I'm test method in class B"
b = B()
b.test()
Output will be....
$ python test.py
I'm test method in class A
As we have seen, B.test() didn't call B.__test() methods, as we might expect. But in fact, this is the correct behavior for __. The two methods called __test() are automatically renamed (mangled) to _A__test() and _B__test(), so they do not accidentally override. When you create a method starting with __ it means that you don't want to anyone to be able to override it, and you only intend to access it from inside its own class.
Two underscores at the beginning and at the end:
When we see a method like __this__, don't call it. This is a method which python is meant to call, not you. Let's take a look:
>>> name = "test string"
>>> name.__len__()
11
>>> len(name)
11
>>> number = 10
>>> number.__add__(40)
50
>>> number + 50
60
There is always an operator or native function which calls these magic methods. Sometimes it's just a hook python calls in specific situations. For example __init__() is called when the object is created after __new__() is called to build the instance...
Let's take an example...
class FalseCalculator(object):
def __init__(self, number):
self.number = number
def __add__(self, number):
return self.number - number
def __sub__(self, number):
return self.number + number
number = FalseCalculator(20)
print number + 10 # 10
print number - 20 # 40
For more details, see the [PEP-8 guide][1]. For more magic methods, see [this PDF][2].
[1]: https://www.python.org/dev/peps/pep-0008/#method-names-and-instance-variables
[2]://github.com/RafeKettler/magicmethods/blob/master/magicmethods.pdf
According to Meaning of Underscores in Python
Single Leading Underscore(_var): Naming convention indicating a name is meant for internal use. Generally not enforced by the Python interpreter (except in wildcard imports) and meant as a hint to the programmer only.
Single Trailing Underscore(var_): Used by convention to avoid naming conflicts with Python keywords.
Double Leading Underscore(__var): Triggers name mangling when used in a class context. Enforced by the Python interpreter.
Double Leading and Trailing Underscore(__var__): Indicates special methods defined by the Python language. Avoid this naming scheme for your own attributes.
Single Underscore(_): Sometimes used as a name for temporary or insignificant variables (“don’t care”). Also: The result of the last expression in a Python REPL.
Sometimes you have what appears to be a tuple with a leading underscore as in
def foo(bar):
return _('my_' + bar)
In this case, what's going on is that _() is an alias for a localization function that operates on text to put it into the proper language, etc. based on the locale. For example, Sphinx does this, and you'll find among the imports
from sphinx.locale import l_, _
and in sphinx.locale, _() is assigned as an alias of some localization function.
Since so many people are referring to Raymond's talk, I'll just make it a little easier by writing down what he said:
The intention of the double underscores was not about privacy. The intention was to use it exactly like this
class Circle(object):
def __init__(self, radius):
self.radius = radius
def area(self):
p = self.__perimeter()
r = p / math.pi / 2.0
return math.pi * r ** 2.0
def perimeter(self):
return 2.0 * math.pi * self.radius
__perimeter = perimeter # local reference
class Tire(Circle):
def perimeter(self):
return Circle.perimeter(self) * 1.25
It's actually the opposite of privacy, it's all about freedom. It makes your subclasses free to override any one method without breaking the others.
Say you don't keep a local reference of perimeter in Circle. Now, a derived class Tire overrides the implementation of perimeter, without touching area. When you call Tire(5).area(), in theory it should still be using Circle.perimeter for computation, but in reality it's using Tire.perimeter, which is not the intended behavior. That's why we need a local reference in Circle.
But why __perimeter instead of _perimeter? Because _perimeter still gives derived class the chance to override:
class Tire(Circle):
def perimeter(self):
return Circle.perimeter(self) * 1.25
_perimeter = perimeter
Double underscores has name mangling, so there's a very little chance that the local reference in parent class get override in derived class. thus "makes your subclasses free to override any one method without breaking the others".
If your class won't be inherited, or method overriding does not break anything, then you simply don't need __double_leading_underscore.
_var: variables with a leading single underscore in python are classic variables, intended to inform others using your code that this variable should be reserved for internal use. They differ on one point from classic variables: they are not imported when doing a wildcard import of an object/module where they are defined (exceptions when defining the __all__ variable). Eg:
# foo.py
var = "var"
_var = "_var"
# bar.py
from foo import *
print(dir()) # list of defined objects, contains 'var' but not '_var'
print(var) # var
print(_var) # NameError: name '_var' is not defined
_ : the single underscore is a special case of the leading single underscore variables. It is used by convention as a trash variable, to store a value that is not intended to be later accessed. It is also not imported by wildcard imports. Eg: this for loop prints "I must not talk in class" 10 times, and never needs to access the _ variable.
for _ in range(10):
print("I must not talk in class")
var_: single trailing underscore variables. They are classic variables used by convention to avoid conflicts with Python keyword. Eg:
class_ = "MyClassName"
__var: double leading underscore variables (at least two leading underscores, at most one trailing underscore). When used as class attributes (variables and methods), these variables are subject to name mangling: outside of the class, python will rename the attribute to _<Class_name>__<attribute_name>. Example:
class MyClass:
__an_attribute = "attribute_value"
my_class = MyClass()
print(my_class._MyClass__an_attribute) # "attribute_value"
print(my_class.__an_attribute) # AttributeError: 'MyClass' object has no attribute '__an_attribute'
When used as variables outside a class, they behave like single leading underscore variables.
__var__: double leading and trailing underscore variables (at least two leading and trailing underscores). Also called dunders. This naming convention is used by python to define variables internally. Avoid using this convention to prevent name conflicts that could arise with python updates. Dunder variables behave like single leading underscore variables: they are not subject to name mangling when used inside classes, but are not imported in wildcard imports.
If one really wants to make a variable read-only, IMHO the best way would be to use property() with only getter passed to it. With property() we can have complete control over the data.
class PrivateVarC(object):
def get_x(self):
pass
def set_x(self, val):
pass
rwvar = property(get_p, set_p)
ronly = property(get_p)
I understand that OP asked a little different question but since I found another question asking for 'how to set private variables' marked duplicate with this one, I thought of adding this additional info here.
Great answers and all are correct.I have provided simple example along with simple definition/meaning.
Meaning:
some_variable --► it's public anyone can see this.
_some_variable --► it's public anyone can see this but it's a convention to indicate private...warning no enforcement is done by Python.
__some_varaible --► Python replaces the variable name with _classname__some_varaible (AKA name mangling) and it reduces/hides it's visibility and be more like private variable.
Just to be honest here According to Python documentation
"“Private” instance variables that cannot be accessed except from
inside an object don’t exist in Python"
The example:
class A():
here="abc"
_here="_abc"
__here="__abc"
aObject=A()
print(aObject.here)
print(aObject._here)
# now if we try to print __here then it will fail because it's not public variable
#print(aObject.__here)
Here is a simple illustrative example on how double underscore properties can affect an inherited class. So with the following setup:
class parent(object):
__default = "parent"
def __init__(self, name=None):
self.default = name or self.__default
#property
def default(self):
return self.__default
#default.setter
def default(self, value):
self.__default = value
class child(parent):
__default = "child"
if you then create a child instance in the python REPL, you will see the below
child_a = child()
child_a.default # 'parent'
child_a._child__default # 'child'
child_a._parent__default # 'parent'
child_b = child("orphan")
## this will show
child_b.default # 'orphan'
child_a._child__default # 'child'
child_a._parent__default # 'orphan'
This may be obvious to some, but it caught me off guard in a much more complex environment
Single leading underscores is a convention. there is no difference from the interpreter's point of view if whether names starts with a single underscore or not.
Double leading and trailing underscores are used for built-in methods, such as __init__, __bool__, etc.
Double leading underscores w/o trailing counterparts are a convention too, however, the class methods will be mangled by the interpreter. For variables or basic function names no difference exists.
Your question is good, it is not only about methods. Functions and objects in modules are commonly prefixed with one underscore as well, and can be prefixed by two.
But __double_underscore names are not name-mangled in modules, for example. What happens is that names beginning with one (or more) underscores are not imported if you import all from a module (from module import *), nor are the names shown in help(module).
“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.
reference
https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references
Getting the facts of _ and __ is pretty easy; the other answers express them pretty well. The usage is much harder to determine.
This is how I see it:
_
Should be used to indicate that a function is not for public use as for example an API. This and the import restriction make it behave much like internal in c#.
__
Should be used to avoid name collision in the inheritace hirarchy and to avoid latebinding. Much like private in c#.
==>
If you want to indicate that something is not for public use, but it should act like protected use _.
If you want to indicate that something is not for public use, but it should act like private use __.
This is also a quote that I like very much:
The problem is that the author of a class may legitimately think "this
attribute/method name should be private, only accessible from within
this class definition" and use the __private convention. But later on,
a user of that class may make a subclass that legitimately needs
access to that name. So either the superclass has to be modified
(which may be difficult or impossible), or the subclass code has to
use manually mangled names (which is ugly and fragile at best).
But the problem with that is in my opinion that if there's no IDE that warns you when you override methods, finding the error might take you a while if you have accidentially overriden a method from a base-class.
In the case of methods, you can use the double underscore to hide away private 'methods' with the following pattern:
# Private methods of MyClass
def _MyClass__do_something(obj:'MyClass'):
print('_MyClass__do_something() called. type(obj) = {}'.format(type(obj)))
class MyClass():
def __init__(self):
__do_something(self)
mc = MyClass()
Output:
_MyClass__do_something() called. type(obj) = <class '__main__.MyClass'>
I stumbled across this today when I tried using double underscore for class methods and got the NameError: name '_<class><method>' is not defined error.
To frame it in simple words, let us compare python's variables' accessibility conventions to access modifiers in Java:
(Python) = (Java)
_single_underscore_variable = Protected (Accessible to class and its subclasses)
__double_underscore_variable = Private (Accessible to class itself only)
no_underscore_variable = Public (Accessible anywhere)
Reference: https://www.tutorialsteacher.com/python/public-private-protected-modifiers

Categories

Resources