Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are Python's 'private' methods not actually private?

Python gives us the ability to create 'private' methods and variables within a class by prepending double underscores to the name, like this: __myPrivateMethod(). How, then, can one explain this

>>>> class MyClass: ...     def myPublicMethod(self): ...             print 'public method' ...     def __myPrivateMethod(self): ...             print 'this is private!!' ... >>> obj = MyClass()  >>> obj.myPublicMethod() public method  >>> obj.__myPrivateMethod() Traceback (most recent call last):   File "<stdin>", line 1, in <module> AttributeError: MyClass instance has no attribute '__myPrivateMethod'  >>> dir(obj) ['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']  >>> obj._MyClass__myPrivateMethod() this is private!! 

What's the deal?!

I'll explain this a little for those who didn't quite get that.

>>> class MyClass: ...     def myPublicMethod(self): ...             print 'public method' ...     def __myPrivateMethod(self): ...             print 'this is private!!' ... >>> obj = MyClass() 

I create a class with a public method and a private method and instantiate it.

Next, I call its public method.

>>> obj.myPublicMethod() public method 

Next, I try and call its private method.

>>> obj.__myPrivateMethod() Traceback (most recent call last):   File "<stdin>", line 1, in <module> AttributeError: MyClass instance has no attribute '__myPrivateMethod' 

Everything looks good here; we're unable to call it. It is, in fact, 'private'. Well, actually it isn't. Running dir() on the object reveals a new magical method that Python creates magically for all of your 'private' methods.

>>> dir(obj) ['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod'] 

This new method's name is always an underscore, followed by the class name, followed by the method name.

>>> obj._MyClass__myPrivateMethod() this is private!! 

So much for encapsulation, eh?

In any case, I'd always heard Python doesn't support encapsulation, so why even try? What gives?

like image 901
willurd Avatar asked Sep 16 '08 08:09

willurd


People also ask

Do private methods exist in Python?

In Python, there is no existence of Private methods that cannot be accessed except inside a class. However, to define a private method prefix the member name with double underscore “__”. Note: The __init__ method is a constructor and runs as soon as an object of a class is instantiated.

Does Python enforce private methods?

The Python interpreter does not enforce this convention when working with classes, it's just a naming convention. Using private methods or private attributes allows you to show other developers which methods or attributes are “for internal use only” in a Python class.

Is __ init __ a private method?

A notable private method in Python is the __init__() method, which is used as a class constructor for a class object. This method is called when an object of a class is instantiated, depending on the method's arguments.

Does Python have public and private methods?

There are three types of access modifiers in Python: public, private, and protected. Variables with the public access modifiers can be accessed anywhere inside or outside the class, the private variables can only be accessed inside the class, while protected variables can be accessed within the same package.


1 Answers

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.

like image 58
Alya Avatar answered Oct 11 '22 11:10

Alya