python logo

Encapsulation

Python hosting: Host, run, and code Python in the cloud!

In an object oriented python program, you can restrict access to methods and variables. This can prevent the data from being modified by accident and is known as encapsulation.   Let’s start with an example.

Related Courses:
Python Programming Bootcamp: Go from zero to hero

Private methods

encapsulation encapsulation. Restricted accesss to methods or variables

We create a class Car which has two methods:  drive() and updateSoftware().  When a car object is created, it will call the private methods __updateSoftware().  

This function cannot be called on the object directly, only from within the class.

#!/usr/bin/env python

class Car:

def __init__(self):
self.__updateSoftware()

def drive(self):
print('driving')

def __updateSoftware(self):
print('updating software')

redcar = Car()
redcar.drive()
#redcar.__updateSoftware() not accesible from object.

This program will output:

updating software
driving

Encapsulation prevents from accessing accidentally, but not intentionally.

The private attributes and methods are not really hidden, they’re renamed adding _Car” in the beginning of their name.

The method can actually be called using redcar._Car__updateSoftware()

Private variables

encapsulation-example Class with private variables

Variables can be private which can be useful on many occasions. A private variable can only be changed within a class method and not outside of the class.

Objects can hold crucial data for your application and you do not want that data to be changeable from anywhere in the code.
An example:

#!/usr/bin/env python

class Car:

__maxspeed = 0
__name = ""

def __init__(self):
self.__maxspeed = 200
self.__name = "Supercar"

def drive(self):
print('driving. maxspeed ' + str(self.__maxspeed))

redcar = Car()
redcar.drive()
redcar.__maxspeed = 10 # will not change variable because its private
redcar.drive()

If you want to change the value of a private variable, a setter method is used.  This is simply a method that sets the value of a private variable.

#!/usr/bin/env python

class Car:

__maxspeed = 0
__name = ""

def __init__(self):
self.__maxspeed = 200
self.__name = "Supercar"

def drive(self):
print('driving. maxspeed ' + str(self.__maxspeed))

def setMaxSpeed(self,speed):
self.__maxspeed = speed

redcar = Car()
redcar.drive()
redcar.setMaxSpeed(320)
redcar.drive()

Why would you create them? Because some of the private values you may want to change after creation of the object while others may not need to be changed at all.

Python Encapsulation


To summarize, in Python there are:

Other programming languages have protected class methods too, but Python does not.

Encapsulation gives you more control over the degree of coupling in your code, it allows a class to change its implementation without affecting other parts of the code.

If you are new to Python programming, I highly recommend this book.

Download Exercises

BackNext





Leave a Reply:




Tomislav Sat, 20 Jun 2015

"If you want to change the value of a private value, an setter method is used. This is simply a method that sets the value of a private value."

there is a typo --> change the value of a private value --> change the value of a private variable

Frank Sat, 20 Jun 2015

Thanks Tomislav! I updated it

Naveen Kerati Tue, 30 Jun 2015

so __ before a method or variable is considered as a private members is it...?

Frank Tue, 30 Jun 2015

Yes, if you put __ before a method or variable it is a private member. This means you can only access it using a method.

Crysis Sat, 25 Jul 2015

It's weird that for python the default access for a variable is public...

Frank Sat, 25 Jul 2015

Hi! It's cultural, in both Python and Java nothing prevents you from declaring all variables public, encapsulation is not strictly enforced in either language. In Java variables are private by default, in Python private variables are not enforced. In practice there is not a lot of difference because the developer has the authority on the code.

Terry Sat, 01 Aug 2015

And in C++ a struct is a class where all the members are public by default.

Terry Sat, 01 Aug 2015

Does Python support namespaces?

Frank Sat, 01 Aug 2015

Hi Terry,

Yes there are namespaces, but there are a variety of ways to implement them.
I would recommend the third method because it's the most clean solution.

Method 1: Use dictionary
Everything is an object in Python, a dictionary can act as a namespace.

#!/usr/bin/env python

class Person:
def sayHi(self):
print('Hi')

person = Person()

def python():
print('Python')

a_namespace = {'person':person, 'python': python}
a_namespace['person'].sayHi()
a_namespace['python']()

Method 2: Use packages
Create a directory /example/demo/ for your package. Inside it create a file called __init__.py with this contents:

#!/usr/bin/env python

def hello():
print('Hello world')


Then on the /example/ directory create a file test.py with this contents:

import demo

demo.hello()



Method 3: Use pkgutil
If you use pkgutil, you can create nested packages. Create a directory using this structure

<ul>
<li>/example/hello/</li>
<li>/example/hello/__init__.py</li>
<li>/example/hello/english/</li>
<li>/example/hello/english/__init__.py</li>
<li>/example/hello/dutch/</li>
<li>/example/hello/dutch/__init__.py</li>
<li>/example/test.py</li>
</ul>

In /example/hello/__init__.py put:

import pkgutil

__path__ = pkgutil.extend_path(__path__, __name__)
__path__.reverse()


In /example/hello/english/__init__.py put:
def hello():
print('Hello')


In /example/hello/dutch/__init__.py put:
def hello():
print('Hallo')


Your package is now complete. You can use nested namespaces.
Add this to /example/test.py and execute it:

import hello.english
import hello.dutch

hello.english.hello()
hello.dutch.hello()

Sajan Bhagat Fri, 07 Aug 2015

first of all __maxspeed is private but i'm still able to access it with object name & another thing when i used print(redcar.__maxspeed) it prints updated value 10 could you please explain the behaviour

Amit Thu, 24 Sep 2015

class Person:
__name #variable

class Programmer(Person)
self_Person__name ------> meaning full explanation please for this

Frank Thu, 24 Sep 2015

Hi Amit,
The class Programmer inherits from the class Person. The Person class has a variable called name. Because Programmer inherits from Person, it has access to the name variable. For more on inheritance, read here.

Jacky Wed, 16 Dec 2015

Hi,Frank
What's the text font in the source code?

Frank Sat, 19 Dec 2015

Hi Jacky, I think it's monospace

Sadia Sat, 20 Feb 2016

Hi Frank,
i am getting problem in file handling. i have written program which count number of lines and total words in file but it is not giving me correctly the number of words. my txt file is :

this is a text file. i have to count its lines and words.
this is a text file. i have to count its lines and words.


this program is giving me 58 words while there are not 58 words. Secondly when i write filename.read instead of filename.readlines then it does not give me correct number of lines. why?

count=0
filename=open("mfile.txt",'r')
handle=filename.readlines()
#print(handle)
for line in handle:
count+=1
print(count)

count_word=0
for word in line:
count_word=count_word+1
print(count_word)
Frank Thu, 25 Feb 2016

If you print word inside the for word loop, it will show it splits the line into single characters. To split into words use this:

count=0
filename=open("mfile.txt",'r')
handle=filename.readlines()
#print(handle)
for line in handle:
count+=1

print(count)

count_word=0
words = line.split(' ')
for word in words:
print word
count_word=count_word+1
print(count_word)

read() and readlines() are different methods. read() takes x characters from a file. readlines() reads the whole file and splits by newlines.

Sadia Sat, 27 Feb 2016

Many thanks :)

Amine Brikci-Nigassa Sun, 16 Apr 2017

"The private method __updateSoftware() can only be called within the class itself. It can never be called from outside the class."
Why don't you tell that the method can actually be called using redcar._Car__updateSoftware() ?
The "private" attributes and methods are not really hidden, they're just automatically renamed adding "_Car" in the beginning of their name... This truly prevents from accessing them *accidentally* but not intentionally...

Frank Sun, 16 Apr 2017

Thanks! I updated the post.

Copyright © 2015 - 2021 - Pythonspot.  | Cookie policy | Terms of use | Privacy policy
Type Description
public methods Accessible from anywhere
private methods Accessible only in their own class. starts with two underscores
public variables Accessible from anywhere
private variables Accesible only in their own class or by a method if defined. starts with two underscores