Why can I not invoke this function at module-level? - python

Issue [python 3.8.6]
def __foo():
pass
class MyClass:
#staticmethod
def bar():
__foo()
MyClass.bar()
results in:
NameError: name '_MyClass__foo' is not defined
Observations
If I replace __foo() with foo(), it runs fine.
I realize python is looking for __foo() inside MyClass. In C++, I can use ::__foo() to explicitly invoke the function at the module level. Is there an equivalent in python?
Questions
Can you explain why I'm getting this error?
How can I keep __foo() and invoke it from inside the Class?
RESOLUTION
I had a misunderstanding about naming conventions in python.
Private methods and symbols in classes have double underscore prefixes, but the same symbols at the module level have single underscore prefixes.

Because any name with two underscores as a prefix (and not a suffix) is mangled inside a class definition statement. 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.
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.
(emphasis added)
The sanest thing is not to name your function with two underscores. Alternatively, you can do something like this:
def __foo():
pass
def bar():
__foo()
class MyClass:
bar = staticmethod(bar)
MyClass.bar()
Or honestly, just keep bar as a module-level function.
But again, using two-underscores doesn't make much sense. If you meant to signal that the function is not a part of the public api of the module, then you should use a single underscore:
def _foo():
pass

Related

Having trouble calling private variables of superclass [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 re-assigning in objects private attribute doesn't complain in python? [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

Unable to access instance variable by name in Django model [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

what is the difference between 'cls.__id' and 'object._object.__id'(private attribute access) [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

Reference to (module only) global function within a class method

In python one can easily refer to a global method by means of it's name.
def globalfoo(a):
print(a)
class myClass:
def test(self):
v = globalfoo
v("hey")
t = myClass()
t.test()
Now in python one can also "hide" a (class) method by prefixing it with two underscores. - And I thought(!) one could do the same for global functions - to make a global function module-only. (Similar to C++ where one can decide to put a function declaration not in the header so it's only visible to the current compilation unit).
I then tried to combine this:
def __globalfoo(a):
print(a)
class myClass:
def test(self):
v = __globalfoo
v("hey")
t = myClass()
t.test()
However this doesn't seem to work, an error is thrown that "_myCLass__globalfoo" is undefined. So how would I make both things work: having a reference to a function. And hiding the function from the external scope?
Is a static method in this case the only/best solution?
And I thought(!) one could do the same for global functions - to make a global function module-only.
You were incorrect. Using a double-underscore name for a module-level function will not prevent it from being used in other modules. Someone can still do import yourmodule and then call yourmodule.__globalfoo.
The double-underscore name mangling behavior is defined in the 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, as long as it occurs within the definition of a class.
It is purely a textual substitution and takes no account of what (if anything) the double-underscore name refers to. It just takes any identifier occurring anywhere inside the class definition that looks like __blah and changes it to _class__blah. It is specific to class definitions and does not occur for module-level functions.
The best thing to do is prefix your function with a single underscore and document that it is not part of the public API and users of the module should not rely on it. There is nothing to be gained by attempting to "enforce" this privacy.
In python, generally, we don't try that hard to make things inaccessible for other things. We trust other developers' not to modify and access things they shouldn't. Anyway, the way the language works it is almost impossible to make those things completely inaccessible.
What you can do is two things. The standard sign of internal functions in modules is a single underscore - and other programmers should know not to meddle with those functions. Python even supports that convention in some aspect - when importing like this:
from module import *
this won't import underscore-prefixed names.
The other way would be to del method at the end of the module. Not very conventional, but if you must it achieves what you want to do:
def func():
pass
...
...
del func

Categories