0% found this document useful (0 votes)
2 views14 pages

Python Lab manual 05

The document outlines the objectives and outcomes of a lab focused on Object-Oriented Programming (OOP) in Python, including creating classes, constructors, objects, and utilizing encapsulation. It explains key concepts such as classes vs instances, instance methods, and the importance of encapsulation in managing data access and modification. Additionally, it covers access modifiers and the use of getters and setters to implement encapsulation effectively.

Uploaded by

aaimarizwan2006
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views14 pages

Python Lab manual 05

The document outlines the objectives and outcomes of a lab focused on Object-Oriented Programming (OOP) in Python, including creating classes, constructors, objects, and utilizing encapsulation. It explains key concepts such as classes vs instances, instance methods, and the importance of encapsulation in managing data access and modification. Additionally, it covers access modifiers and the use of getters and setters to implement encapsulation effectively.

Uploaded by

aaimarizwan2006
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

Lab#05 - OOP in python

Objectives:
➢ To learn and able to create class, constructor and object
➢ To learn and able to create instance variable, class variable and member functions
➢ learn and able to use encapsulation (public, private and protected)
➢ To learn and able to use setter and getter

Outcomes:

Students should be able to create class, constructor and object
➢ Students should be able to create instance variable, class variable and member functions
➢ Students should be able to use encapsulation (public, private and protected)
➢ Students should be able to use setter and getter

5.1 OOP

Object-oriented programming (OOP) is a method of structuring a program by bundling related properties and behaviors into
individual objects. In this tutorial, you’ll learn the basics of object-oriented programming in Python.

Conceptually, objects are like the components of a system. Think of a program as a factory assembly line of sorts. At each
step of the assembly line a system component processes some material, ultimately transforming raw material into a finished
product.

5.2 What Is Object-Oriented Programming in Python?

Object-oriented programming is a programming paradigm that provides a means of structuring programs so that properties
and behaviors are bundled into individual objects.

For instance, an object could represent a person with properties like a name, age, and address and behaviors such as walking,
talking, breathing, and running. Or it could represent an email with properties like a recipient list, subject, and body and
behaviors like adding attachments and sending.

Put another way, object-oriented programming is an approach for modeling concrete, real-world things, like cars, as well as
relations between things, like companies and employees, students and teachers, and so on. OOP models real-world entities
as software objects that have some data associated with them and can perform certain functions.

Another common programming paradigm is procedural programming, which structures a program like a recipe in that it
provides a set of steps, in the form of functions and code blocks, that flow sequentially in order to complete a task.

The key takeaway is that objects are at the center of object-oriented programming in Python, not only representing the data,
as in procedural programming, but in the overall structure of the program as well.

5.3 Define a Class in Python

pg. 1
Primitive data structures—like numbers, strings, and lists—are designed to represent simple pieces of information, such as
the cost of an apple, the name of a poem, or your favorite colors, respectively. What if you want to represent something
more complex?

For example, let’s say you want to track employees in an organization. You need to store some basic information about
each employee, such as their name, age, position, and the year they started working.

One way to do this is to represent each employee as a list:

There are a number of issues with this approach.

First, it can make larger code files more difficult to manage. If you reference kirk[0] several lines away from where the kirk
list is declared, will you remember that the element with index 0 is the employee’s name?

Second, it can introduce errors if not every employee has the same number of elements in the list. In the mccoy list above,
the age is missing, so mccoy[1] will return "Chief Medical Officer" instead of Dr. McCoy’s age.

A great way to make this type of code more manageable and more maintainable is to use classes.

5.3.1 Classes vs Instances

Classes are used to create user-defined data structures. Classes define functions called methods, which identify the behaviors
and actions that an object created from the class can perform with its data.

In this tutorial, you’ll create a Dog class that stores some information about the characteristics and behaviors that an
individual dog can have.

A class is a blueprint for how something should be defined. It doesn’t actually contain any data. The Dog class specifies
that a name and an age are necessary for defining a dog, but it doesn’t contain the name or age of any specific dog.

While the class is the blueprint, an instance is an object that is built from a class and contains real data. An instance of the
Dog class is not a blueprint anymore. It’s an actual dog with a name, like Miles, who’s four years old.

Put another way, a class is like a form or questionnaire. An instance is like a form that has been filled out with information.
Just like many people can fill out the same form with their own unique information, many instances can be created from a
single class.

5.3.2 How to Define a Class

All class definitions start with the class keyword, which is followed by the name of the class and a colon. Any code that is
indented below the class definition is considered part of the class’s body.

Here’s an example of a Dog class:


pg. 2
The body of the Dog class consists of a single statement: the pass keyword. pass is often used as a placeholder indicating
where code will eventually go. It allows you to run this code without Python throwing an error.

The Dog class isn’t very interesting right now, so let’s spruce it up a bit by defining some properties that all Dog objects
should have. There are a number of properties that we can choose from, including name, age, coat color, and breed. To keep
things simple, we’ll just use name and age.

The properties that all Dog objects must have are defined in a method called .__init__(). Every time a new Dog object is
created, .__init__() sets the initial state of the object by assigning the values of the object’s properties. That is, .__init__()
initializes each new instance of the class.

You can give .__init__() any number of parameters, but the first parameter will always be a variable called self. When a
new class instance is created, the instance is automatically passed to the self parameter in .__init__() so that new attributes
can be defined on the object.

Let’s update the Dog class with an .__init__() method that creates .name and .age attributes:

Notice that the .__init__() method’s signature is indented four spaces. The body of the method is indented by eight spaces.
This indentation is vitally important. It tells Python that the .__init__() method belongs to the Dog class.

In the body of .__init__(), there are two statements using the self variable:

• self.name = name creates an attribute called name and assigns to it the value of the name parameter.
• self.age = age creates an attribute called age and assigns to it the value of the age parameter.
Attributes created in .__init__() are called instance attributes. An instance attribute’s value is specific to a particular instance
of the class. All Dog objects have a name and an age, but the values for the name and age attributes will vary depending on
the Dog instance.

On the other hand, class attributes are attributes that have the same value for all class instances. You can define a class
attribute by assigning a value to a variable name outside of .__init__().

For example, the following Dog class has a class attribute called species with the value "Canis familiaris":

pg. 3
Class attributes are defined directly beneath the first line of the class name and are indented by four spaces. They must
always be assigned an initial value. When an instance of the class is created, class attributes are automatically created and
assigned to their initial values.

Use class attributes to define properties that should have the same value for every class instance. Use instance attributes for
properties that vary from one instance to another.

Now that we have a Dog class, let’s create some dogs!

5.4 Instantiate an Object in Python

Open IDLE’s interactive window and type the following:

This creates a new Dog class with no attributes or methods.

Creating a new object from a class is called instantiating an object. You can instantiate a new Dog object by typing the name
of the class, followed by opening and closing parentheses:

You now have a new Dog object at 0x106702d30. This funny-looking string of letters and numbers is a memory address
that indicates where the Dog object is stored in your computer’s memory. Note that the address you see on your screen will
be different.

Now instantiate a second Dog object:

The new Dog instance is located at a different memory address. That’s because it’s an entirely new instance and is
completely unique from the first Dog object that you instantiated.

To see this another way, type the following:

pg. 4
In this code, you create two new Dog objects and assign them to the variables a and b. When you compare a and b using the
== operator, the result is False. Even though a and b are both instances of the Dog class, they represent two distinct objects
in memory.

5.4.1 Class and Instance Attributes

Now create a new Dog class with a class attribute called .species and two instance attributes called .name and .age:

To instantiate objects of this Dog class, you need to provide values for the name and age. If you don’t, then Python raises a
TypeError:

To pass arguments to the name and age parameters, put values into the parentheses after the class name:

pg. 5
This creates two new Dog instances—one for a nine-year-old dog named Buddy and one for a four-year-old dog named
Miles.

The Dog class’s .__init__() method has three parameters, so why are only two arguments passed to it in the example?

When you instantiate a Dog object, Python creates a new instance and passes it to the first parameter of .__init__(). This
essentially removes the self parameter, so you only need to worry about the name and age parameters.

After you create the Dog instances, you can access their instance attributes using dot notation:

You can access class attributes the same way:

One of the biggest advantages of using classes to organize data is that instances are guaranteed to have the attributes you
expect. All Dog instances have .species, .name, and .age attributes, so you can use those attributes with confidence knowing
that they will always return a value.

Although the attributes are guaranteed to exist, their values can be changed dynamically:

In this example, you change the .age attribute of the buddy object to 10. Then you change the .species attribute of the miles
object to "Felis silvestris", which is a species of cat. That makes Miles a pretty strange dog, but it is valid Python!

The key takeaway here is that custom objects are mutable by default. An object is mutable if it can be altered dynamically.
For example, lists and dictionaries are mutable, but strings and tuples are immutable.

5.4.2 Instance Methods

Instance methods are functions that are defined inside a class and can only be called from an instance of that class. Just like
.__init__(), an instance method’s first parameter is always self.

pg. 6
Open a new editor window in IDLE and type in the following Dog class:

This Dog class has two instance methods:

• .description() returns a string displaying the name and age of the dog.
• .speak() has one parameter called sound and returns a string containing the dog’s name and the sound the dog makes.
Save the modified Dog class to a file called dog.py and run the program. Then open the interactive window and type the
following to see your instance methods in action:

In the above Dog class, .description() returns a string containing information about the Dog instance miles. When writing
your own classes, it’s a good idea to have a method that returns a string containing useful information about an instance of
the class. However, .description() isn’t the most Pythonic way of doing this.

When you create a list object, you can use print() to display a string that looks like the list:

Let’s see what happens when you print() the miles object:

pg. 7
When you print(miles), you get a cryptic looking message telling you that miles is a Dog object at the memory address
0x00aeff70. This message isn’t very helpful. You can change what gets printed by defining a special instance method called
.__str__().

In the editor window, change the name of the Dog class’s .description() method to .__str__():

Methods like .__init__() and .__str__() are called dunder methods because they begin and end with double underscores.
There are many dunder methods that you can use to customize classes in Python. Although too advanced a topic for a
beginning Python book, understanding dunder methods is an important part of mastering object-oriented programming in
Python.

In the next section, you’ll see how to take your knowledge one step further and create classes from other classes.

5.5 Encapsulation in Python

Encapsulation is one of the fundamental concepts in object-oriented programming (OOP), including abstraction, inheritance,
and polymorphism. This lesson will cover what encapsulation is and how to implement it in Python.

After reading this article, you will learn:

• Encapsulation in Python
• Need for Encapsulation
• Data Hiding using public, protected, and private members
• Data Hiding vs. Encapsulation
• Getter and Setter Methods
• Benefits of Encapsulation

6.6 What is Encapsulation in Python?


Encapsulation in Python describes the concept of bundling data and methods within a single unit. So, for example, when
you create a class, it means you are implementing encapsulation. A class is an example of encapsulation as it binds all the
data members (instance variables) and methods into a single unit.

pg. 8
Example:

In this example, we create an Employee class by defining employee attributes such as name and salary as an instance variable
and implementing behavior using work() and show() instance methods.

Using encapsulation, we can hide an object’s internal representation from the outside. This is called information hiding.

Also, encapsulation allows us to restrict accessing variables and methods directly and prevent accidental data modification
by creating private data members and methods within a class.

Encapsulation is a way to can restrict access to methods and variables from outside of class. Whenever we are working with
the class and dealing with sensitive data, providing access to all variables used within the class is not a good choice.

For example, Suppose you have an attribute that is not visible from the outside of an object and bundle it with methods that
provide read or write access. In that case, you can hide specific information and control access to the object’s internal state.
Encapsulation offers a way for us to access the required variable without providing the program full-fledged access to all
variables of a class. This mechanism is used to protect the data of an object from other objects.

5.7 Access Modifiers in Python

pg. 9
Encapsulation can be achieved by declaring the data members and methods of a class either as private or protected. But In
Python, we don’t have direct access modifiers like public, private, and protected. We can achieve this by using single
underscore and double underscores.

Access modifiers limit access to the variables and methods of a class. Python provides three types of access modifiers
private, public, and protected.

• Public Member: Accessible anywhere from outside class.


• Private Member: Accessible within the class
• Protected Member: Accessible within the class and its sub-classes

5.7.1 Public Member

Public data members are accessible within and outside of a class. All member variables of the class are by default public.

Example:

pg. 10
5.7.2 Private Member

We can protect variables in the class by marking them private. To define a private variable add two underscores as a prefix
at the start of a variable name.

Private members are accessible only within the class, and we can’t access them directly from the class objects.

Example:

In the above example, the salary is a private variable. As you know, we can’t access the private variable from the outside of
that class.

We can access private members from outside of a class using the following two approaches

Create public method to access private members

Use name mangling

Let’s see each one by one

5.7.3 Public method to access private members

Example: Access Private member outside of a class using an instance method

pg. 11
5.7.4 Name Mangling to access private members

We can directly access private and protected variables from outside of a class through name mangling. The name mangling
is created on an identifier by adding two leading underscores and one trailing underscore, like this
_classname__dataMember, where classname is the current class, and data member is the private variable name.

Example: Access private member

5.7.5 Protected Member

Protected members are accessible within the class and also available to its sub-classes. To define a protected member, prefix
the member name with a single underscore _.

pg. 12
Protected data members are used when you implement inheritance and want to allow data members access to only child
classes.

Example: Proctecd member in inheritance.

5.8 Getters and Setters in Python

To implement proper encapsulation in Python, we need to use setters and getters. The primary purpose of using getters and
setters in object-oriented programs is to ensure data encapsulation. Use the getter method to access data members and the
setter methods to modify the data members.

In Python, private variables are not hidden fields like in other programming languages. The getters and setters methods are
often used when:

• When we want to avoid direct access to private variables


• To add validation logic for setting a value

Example

pg. 13
5.9 Advantages of Encapsulation

• Security: The main advantage of using encapsulation is the security of the data. Encapsulation protects an object
from unauthorized access. It allows private and protected access levels to prevent accidental data modification.
• Data Hiding: The user would not be knowing what is going on behind the scenes. They would only know that to
modify a data member, call the setter method. To read a data member, call the getter method. What these setter and
getter methods are doing is hidden from them.
• Simplicity: It simplifies the maintenance of the application by keeping classes separated and preventing them from
tightly coupling with each other.
• Aesthetics: Bundling data and methods within a class makes code more readable and maintainable.

pg. 14

You might also like