Is it possible to make a public method private in a subclass ? I don't want other classes extending this one to be able to call some of the methods . Here is an example :
class A:
def __init__(self):
#do something here
def method(self):
#some code here
class B(A):
def __init__(self):
A.__init__(self)
#additional initialization goes here
def method(self):
#this overrides the method ( and possibly make it private here )
from this point forward , I don't want any class that extends from B to be able to call method
.
Is this possible ?
EDIT : a "logical" reason for this is that I don't want users to call methods in wrong order.
http://linuxwell.com/2011/07/21/private-protected-and-public-in-python/
This may be a fair approximation. Lexical scoping to the "rescue":
Prints:
I am surprised that no one has mentioned this, but prefixing the method name with a single underscore is the correct way of labelling it as "private". It's not really private of course, (as explained in other answers), but there you go.
"Everything must be public" proponents think the author is trying to hide a useful API from the users. This guy doesn't want to violate an unquestionable law of Python. He wants to use some methods to define a useful API, and he wants to use other methods to organize the implementation of that API. If there's no separation between the two it doesn't mean the author is not an idiot. It means the author was too lazy to actually define an API.
In Python, instead of marking properties or methods as private, they may be prefixed with
_
as a weak "internal use" indicator, or with__
as a slightly stronger one. In a module, names may be prefixed with_
in the same way, and you may also put a sequence of strings that constitute the modules' public API in a variable called__all__
.A foolish consistency is the hobgoblin of little minds.
Changing an inherited method from public to private breaks inheritance. Specifically, it breaks the is-a relationship.
Imagine a Restaurant class with a open-doors public method (i.e. it's dinnertime and we want to flip the front door sign from closed to open). Now we want a Catering class that would share many of the implementation details of Restaurant (they both need cooks, kitchens, dishes, food suppliers, and maybe even waitstaff), but not have a dining area, front doors, or the open-doors method. Inheritance from Restaurant is a mistake! It might appear that all you need to do is change the open-doors method to private so no one can use it, but then "any Catering object is-a Restaurant" is false, since part of Restaurant's public interface is open-doors. It's better to refactor Restaurant by adding a new base class and then both Restaurant and Catering derive from it.
Languages with a notion of protected or private inheritance support this idea of inheritance for implementation only, but Python is not one of those. (Nor is it useful in those languages, except rarely.) Usually when non-public inheritance is sought, containment (aka "has-a relationship") is the better path, you can even make the attribute protected or private.
Python spells protected with a single leading underscore and private with double leading underscores, with the modification of the "consenting adults" philosophy mentioned in Triptych's answer. "Dangerous" attributes and methods of your class, e.g. ones that might cause data loss, should be non-public (whether to make them protected or private is influenced by other factors), with public methods used to provide a simpler, safer interface.
There are many good answers in this thread but here is somewhat opinionated answer from practical point of view:
You do need to avoid crud of private members from public APIs, intellisense, docs,
import *
etc. So always attach _ or __ to these members.The big question: Should it be _ or __? The purist OOP perspective is to always attach __ to private members and _ for protected methods. The __ does name mangling and makes it hard to use things like setattrib, test frameworks and reduces readability. So my personal view is to avoid __ as much as possible and use _ for private members.
But what about protected members which we want derived class to use but not as public API. My preference here is to use no underscore at all. This allows these members to get in public docs. We then rely on docstring to tell user that these are protected members like this: