Can someone please explain the exact meaning of having leading underscores before an object's name in Python? Also, explain the difference between a single and a double leading underscore. Also, does that meaning stay the same whether the object in question is a variable, a function, a method, etc.?
相关问题
- how to define constructor for Python's new Nam
- streaming md5sum of contents of a large remote tar
- How to get the background from multiple images by
- Evil ctypes hack in python
- Correctly parse PDF paragraphs with Python
“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
Here is a simple illustrative example on how double underscore properties can affect an inherited class. So with the following setup:
if you then create a child instance in the python REPL, you will see the below
This may be obvious to some, but it caught me off guard in a much more complex environment
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 modulefoobar
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 asput
andget
(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).Sometimes you have what appears to be a tuple with a leading underscore as in
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
and in sphinx.locale, _() is assigned as an alias of some localization function.
._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 variablesYou can still access
.__mangled
variables if you desperately want to. The double underscores just namemangles, or renames, the variable to something likeinstance._className__mangled
Example:
t._b is accessible because it is only hidden by convention
t.__a isn't found because it no longer exists due to namemangling
By accessing
instance._className__variable
instead of just the double underscore name, you can access the hidden valueGetting 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 likeprivate
use__
.This is also a quote that I like very much:
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.