Private (implementation) class in Python
Use a single underscore prefix:
class _Internal:
...
This is the official Python convention for 'internal' symbols; "from module import *" does not import underscore-prefixed objects.
Reference to the single underscore convention.
Does Python have “private” variables in classes?
It's cultural. In Python, you don't write to other classes' instance or class variables. In Java, nothing prevents you from doing the same if you really want to - after all, you can always edit the source of the class itself to achieve the same effect. Python drops that pretence of security and encourages programmers to be responsible. In practice, this works very nicely.
If you want to emulate private variables for some reason, you can always use the __
prefix from PEP 8. Python mangles the names of variables like __foo
so that they're not easily visible to code outside the namespace that contains them (although you can get around it if you're determined enough, just like you can get around Java's protections if you work at it).
By the same convention, the _
prefix means _variable
should be used internally in the class (or module) only, even if you're not technically prevented from accessing it from somewhere else. You don't play around with another class's variables that look like __foo
or _bar
.
Calling private function within the same class python
There is no implicit this->
in Python like you have in C/C++ etc. You have to call it on self
.
class Foo:
def __bar(self, arg):
#do something
def baz(self, arg):
self.__bar(arg)
These methods are not really private though. When you start a method name with two underscores Python does some name mangling to make it "private" and that's all it does, it does not enforce anything like other languages do. If you define __bar
on Foo
, it is still accesible from outside of the object through Foo._Foo__bar
. E.g., one can do this:
f = Foo()
f._Foo__bar('a')
This explains the "odd" identifier in the error message you got as well.
You can find it here
in the docs.
Why are Python's 'private' methods not actually private?
The name scrambling is used to ensure that subclasses don't accidentally override the private methods and attributes of their superclasses. It's not designed to prevent deliberate access from outside.
For example:
>>> class Foo(object):
... def __init__(self):
... self.__baz = 42
... def foo(self):
... print self.__baz
...
>>> class Bar(Foo):
... def __init__(self):
... super(Bar, self).__init__()
... self.__baz = 21
... def bar(self):
... print self.__baz
...
>>> x = Bar()
>>> x.foo()
42
>>> x.bar()
21
>>> print x.__dict__
{'_Bar__baz': 21, '_Foo__baz': 42}
Of course, it breaks down if two different classes have the same name.
Private members in Python
9.6. Private Variables
“Private” instance variables that
cannot be accessed except from inside
an object, don’t exist in Python.
However, there is a convention that is
followed by most Python code: a name
prefixed with an underscore (e.g.
_spam) should be treated as a non-public part of the API (whether it
is a function, a method or a data
member). It should be considered an
implementation detail and subject to
change without notice.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.
So, for example,
class Test:
def __private_symbol(self):
pass
def normal_symbol(self):
pass
print dir(Test)
will output:
['_Test__private_symbol',
'__doc__',
'__module__',
'normal_symbol']
__private_symbol
should be considered a private method, but it would still be accessible through _Test__private_symbol
.
Making a method private in a python subclass
Python is distributed as source. The very idea of a private method makes very little sense.
The programmer who wants to extend B
, frustrated by a privacy issue, looks at the source for B
, copies and pastes the source code for method
into the subclass C
.
What have you gained through "privacy"? The best you can hope for is to frustrate your potential customers into copying and pasting.
At worst, they discard your package because they can't extend it.
And yes, all open source is extended in one way or another. You can't foresee everything and every use to which you code will be put. Preventing some future use is hard to do when the code is distributed as source.
See How do I protect Python code?
Edit On "idiot-proof" code.
First, python is distributed as source 90% of the time. So, any idiot who downloads, installs, and then refuses to read the API guide and calls the methods out of order still has the source to figure out what went wrong.
We have three classes of idiots.
People who refuse to read the API guide (or skim it and ignore the relevant parts) and call the methods out of order in spite of the documentation. You can try to make something private, but it won't help because they'll do something else wrong -- and complain about it. [I won't name names, but I've worked with folks who seem to spend a lot of time calling the API's improperly. Also, you'll see questions like this on SO.]
You can only help them with a working code sample they can cut and paste.
People who are confused by API's and call the methods every different way you can imagine (and some you can't.) You can try to make something private, but they'll never get the API.
You can only help them by providing the working code sample; even then, they'll cut and paste it incorrectly.
People who reject your API and want to rewrite it to make it "idiot proof".
You can provide them a working code sample, but they don't like your API and will insist on rewriting it. They'll tell you that your API is crazy and they've improved on it.
You can engage these folks in an escalating arms race of "idiot-proofing". Everything you put together they take apart.
At this point, what has privacy done for you? Some people will refuse to understand it; some people are confused by it; and some people want to work around it.
How about public, and let the folks you're calling "idiots" learn from your code?
Python - Multiple private implementations for a class
Instead of composition, you could consider using a Abstract Base Class, with three different subclasses.
In python, duck typing is favoured over explicitly checking types.
Private methods in Python
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
Related Topics
Site Matching Query Does Not Exist
Asyncio.Gather VS Asyncio.Wait
Split Views.Py in Several Files
Any Gotchas Using Unicode_Literals in Python 2.6
Selenium: Get Coordinates or Dimensions of Element with Python
Efficient Way to Remove Keys with Empty Strings from a Dict
Python Curve_Fit with Multiple Independent Variables
Python: Start New Command Prompt on Windows and Wait for It Finish/Exit
How Would I Make a Method Which Is Run Every Time a Frame Is Shown in Tkinter
Import Win32API Error in Python 2.6
Pandas: Resample Timeseries with Groupby
Check If a Given Key Already Exists in a Dictionary and Increment It
How to Display a 3D Plot of a 3D Array Isosurface in Matplotlib Mplot3D or Similar
How to Programmatically Set a Global (Module) Variable