One of the ways to simplify a program is to1 use objects, classes and functions.
In this tutorial, you will learn the very basics of Object-Oriented programming in Python.
But first, to the basics.
Basically, there are two methods in programming which are:
- Functional programming
- Object-oriented programming(OOP)
I’m sure that you have come across these terms.
If you were confused I will help you out.
Functional programming is about using functions and object-oriented programming is about using classes.
Object-oriented programming involves the use of objects, classes and methods to solve problems.
What’s the difference between a class and a function?
A function contains a block of code that performs only one operation. The operation of the function can be accessed by calling the function’s name.
While a class, contains several functions. The functions in a class can be accessed with an object.
The next difference is dumb but I said let me include it.
When you want to write a function you begin with the keyword “def”. For a class, you begin with the keyword “class”.
Traditionally, class names are capitalized while methods (functions in a class) are not capitalized.
Yes, Python is an Object-oriented programming language. Any one writing a program in Python can define new classes of object and use them. The programmer is not restricted to Python built-in classes of object. Examples of Python built-in classes are int, file, str etc.
That’s one of the reasons I love Python.
Before I define a class, let me tell you something (just an important side talk).
I love playing monopoly. The game of monopoly involves players rolling two dice and moving their piece on the board.
To explain what class in Python programming is, I will write a little program to simulate the game of monopoly.
The below code snippet is saved as monopoly.py in the source code download folder.
1234567891011121314151617181920212223242526272829 | import randomclass Monopoly():"""A simulation of the game of monopoly"""def rollDice(self):self.die1=random.randint(1,6)self.die2=random.randint(1,6)self.steps= self.die1 + self.die2print ("Move",self.steps,"steps on the board.")player1= Monopoly()player2= Monopoly()def playGame():player1.rollDice()player2.rollDice()def attribute():"""Returns the atrributes and values of the attribute in the class, Monopoly"""print(player1.__dict__)playGame()attribute() |
The monopoly.py program simply rolls the dice for player1 and player2 and returns the number of steps each player has to move on the board.
Note the following in this program
- The class name is Monopoly. It is good practice to start your class name with a capital letter.
- The objects of the class Monopoly are player1 and player2
- The function name rollDice is a method
- The attributes of player1 and player2 are die1, die2 and steps
- The instance variable in the class is “self”
- player1 and player2 are not only objects but are global variables because they can be used by the functions playGame and attribute
You will understand this terms as you continue to read.
So what is a class in Python programming?
Tony Gaddis defined a class as a code that specifies the data attributes and methods for a particular type of object.
Source: Starting Out with Python (second edition).
A data attribute is an element of a class. Therefore, die1, die2 and steps are attributes of the class Monopoly. You can also say that the attribute(s) defines the class.
The function attribute returns the attributes and their value in the class Monopoly. To get the attributes in the class, use this format,
object.__dict__
An object is a variable use to access the class. player1 and player2 are objects use to access the class Monopoly.
How To Store Your Classes in Modules
Storing your classes in a separate file hides the details of your code. It also allows you to use the class in another program by just importing it.
Note:
When you want to import a class to another program, make sure your program files are saved in the same folder.
To illustrate this, I will write a phone book program using class.
Open a new file editor and save this code snippet as phonebook.py
12345678910111213141516171819 | class Phone_book():def __init__(self):self.contact_details={}def add_contact(self,name,number):self.contact_details[name]=numberdef remove_contact(self,name):if name in self.contact_details:del self.contact_details[name]else:print("Contact not available")def get_contact_number(self,name):if name in self.contact_details:return self.contact_details.get(name,None)else:print("Contact not available") |
If you didn’t understand the basics of the above code, I advice you go through Python dictionary again.
Alright, now I will write a program that imports the Phonebook module and creates an instance of the Phonebook class.
Remember, an instance is an object associated to a class. Also, the __init__ function(method) will be explained later.
Open a new file editor and paste the below code snippet. Save the program as phonebook_demo.py.
123456789 | from phonebook import *def main():godson = Phone_book()godson.add_contact("Dad","+2347085734411")print(godson.get_contact_number("Dad"))if __name__ == "__main__":main() |
Note:
You have to create an instance of the class Phone_book and that’s what this line of code (godson = Phone_book() ) does.
Am sure you now know how to save and import your class as modules.
How to make an attribute in a class private
To understand how to make a Python class attribute private, let us write a simple program to toss a coin.
Type the below code snippet in a new file editor and save it as TossDie.py
12345678910111213141516171819202122 | import randomclass Die():def toss(self):self.side_up = random.choice(range(1,7))def get_sideup(self):return self.side_updef main():myDie = Die()print("I'm tossing the die")myDie.toss()myDie.side_up = 10print("The side up is",myDie.get_sideup())if __name__ == "__main__":main()main()main() |
Here’s the output of the above snippet:
123456 | I'm tossing the dieThe side up is 10I'm tossing the dieThe side up is 10I'm tossing the dieThe side up is 10 |
Observe that the value 10 in the output doesn’t change.
This is strange because first we imported the module random.
Secondly, random.choice(range(1,7)) returns randomly, an integer from 1 through 6.
Moreover, a die doesn’t have the value 10 on its side.
Therefore, why is 10 our output?
The problem is found in the function main.
By writing this line of code, myDie.side_up=10 , we change the value of the attribute, side_up(self.side_up) to 10.
This is because our attribute is not private and hence it can be modified outside the class.
To make an attribute private in a class, you will have to add two underscores at the beginning of an attribute.
Here is the correction of TossDie.py program
12345678910111213141516171819202122 | import randomclass Die():def toss(self):self.__side_up = random.choice(range(1,7))def get_sideup(self):return self.__side_updef main():myDie = Die()print("I'm tossing the die")myDie.toss()myDie.side_up = 10print("The side up is",myDie.get_sideup())if __name__ == "__main__":main()main()main() |
As I ran the program above, Here’s my result:
1234567891011 | I'm tossing the dieThe side up is 4I'm tossing the dieThe side up is 5I'm tossing the dieThe side up is 6 |
Note:
Even with this line of code myDie.side_up = 10, the attribute side_up doesn’t change to 10.
Making your attributes private prevents the value of the attribute from being modified outside the class.
A method is any function defined in a class. A special Python class method starts and ends with two underscores. There are many special class methods but I will only look at the one I feel that’s so important.
__init__() constructor method:
To explain the __init__() method, open a new editor and copy the below code snippet. Save it as my_info.py
123456789101112131415161718192021 | class MyInfo():def __init__(self,name,age):self.name=nameself.age=ageprint(self.name,"is",self.age,"years old.")def getStatus(self):self.status="Single"print(self.name,"is",self.status)def main():data1=MyInfo("Godson",21)data1.getStatus()print(data1.__dict__)main() |
Here’s the output of the program above.
12345 | Godson is 21 years old.Godson is Single{'name': 'Godson', 'age': 21, 'status': 'Single'} |
In the my_info.py program, there are two methods which are:
- __init__() method
- getStatus()
Did you noticed that I didn’t call the __init__() method but “Godson is 21 years old.
” was an output when I ran the program.
Also I had to call the getStatus() method (data1.getStatus()) to print out “Godson is Single”
Let me further explain this to you.
The __init__ method is also called a Python class constructor or an initializer method; because it runs automatically when the programmer creates an instance of the class. It is the first method defined in a class.
Any object you make from a class is called an instance. In the my_info.py program, data1 is an instance to the class MyInfo.
Note:
When defining a method in a class, start with the parameter “self”. The other parameters such as name, age including self are known as instance variables.
Click here to know the function of the self variable.
As I’ve explained before print(data1.__dict__) returns a dictionary in which the key is the attribute and the value associated to the attribute. This is why we had {‘name’: ‘Godson’, ‘age’: 21, ‘status’: ‘Single’} as an output.
What’s the difference between method and function?
When defining a method, the first argument or parameter passed is self. The self parameter is not required when defining a function.
Note:
All the parameters passed in a method are known as instance variables.
__str__() method
Whenever you want to create a string representation of an object, you use the __str__ method. It is similar to the str() Python built-in function. It is advisable to include this method in your program as it aids in debugging. It would be nice to always know the state of an object after running a new method.
To illustrate the __str__() method, I will write a simple program to buy bitcoins and the program name is bitcoin.py
1234567891011121314151617181920 | class Bitcoin():def __init__(self):self.__btc_value = 100self.__my_btcs = 0def buy_bitcoin(self,amount):self.__my_btcs += amount / self.__btc_valuedef sell_bitcoin(self,btc):if btc <= self.__my_btcs:self.__my_btcs -= btcelse:print("You don't have enough Bitcoins")def available_bitcoin(self):return self.__my_btcsdef __str__(self):return "You have " + str(format(self.__my_btcs,",.2f")) + " Bitcoins" |
The __init__ method initializes the attributes __btc_value and __my_btcs with 100 and 0 respectively. __btc_value represents the value of bitcoin and __my_btcs represents the number of my bitcoins.
The method buy_bitcoin buys bitcoins, the sell_bitcoin sells bitcoins and the available_bitcoin returns the number of bitcoins available.
The __str__ method returns a string representation of the object’s state.
The next program bitcoin_demo.py imports the bitcoin class module and creates an instance of the Bitcoin class.
1234567891011121314151617181920212223 | from bitcoin import *def main():my_wallet = Bitcoin()print("1 bitcoin sells at $100")purchase = float(input("How much cash do you've to buy:"))my_wallet.buy_bitcoin(purchase)print(my_wallet)print("Do you want to send your bitcoin?")sell= float(input("How many bitcoins do you want to sell:"))my_wallet.sell_bitcoin(sell)print(my_wallet)if __name__ == "__main__":main() |
Whenever you want Python to call the __str__ method just use this syntax,
print(class instance)
In the bitcoin_demo.py program, the class instance is “my_wallet”.
There are two ways to do this and they are:
- Directly modifying the attribute’s value
- Using a method to modify the value of the attribute
Directly Modifying the Attribute’s Value
This has been treated when I showed you how to make your class attributes private and I told you that this is important because it prevents the value of the attribute from being modified outside the class.
But any way, writing more codes will make you prefect so I will write a program in which an attribute’s value is modified directly.
Type the below code snippet in a new file editor and save it as student_info.py
Here is the output of the above code snippet
Explanation of the above code snippet.
In the init function the student_CGPA attribute is assigned a default value (4.0), that’s why I didn’t make it an instance variable. That is, the student_CGPA was not passed as parameter in the init function.
This line of code below,
student1.student_CGPA = 4.5
Basically tells Python to take the instance student1, find the attribute student_CGPA associated with it and set the value of that attribute to 4.5.
This is basically how you can modify an attribute directly.
Using a method to modify the value of the attribute
To change or check the value of an attribute of a class in a safe way, we use mutators and accessors methods.
A mutator is a method that changes the value of an attribute and an accessor is a method that returns the value of an attribute.
Take a good look at the code below:
1234567891011121314151617 | class Employee_details():def __init__(self,name,position):self.employee_name = nameself.employee_position = positiondef set_employee_name(self,name):self.employee_name = namedef set_employee_position(self,position):self.employee_position = positiondef get_employee_name(self):return self.employee_namedef get_employee_position(self):return self.employee_position |
Can you point out the accessor and mutator methods?
If you can’t, don’t feel bad.
Here are the mutator methods:
- set_employee_name
- set_employee_position
Here are the accessor methods:
- get_employee_name
- get_employee_position
It is advisable to start your mutator names with set and your accessor names with get.
How to Store Objects in a List.
Storing objects in list can make your work easier and present your objects in a nice way to a client.
I wrote a Python program(course_list.py) to create objects which are my courses and store the objects(courses) in a list and display the list of courses.
Here is the code snippet:
1234567891011121314151617181920212223242526272829303132 | class Courses():def set_course(self,course):self.course = coursedef get_course(self):return self.coursedef create_list():course_list = []print ("Enter nothing to quit")while True:courses = input("Enter the course you did:")if courses == "":breakyear_4_courses = Courses()year_4_courses.set_course(courses)course_list.append(year_4_courses)return course_listdef display_list(course_list):for my_course in course_list:print(my_course.get_course())def main():chemical_courses = create_list()print("Here is your course list")display_list(chemical_courses)if __name__ == "__main__":main() |
Am sure if you go through the above code snippet thoroughly, you won’t have any problem.
But if you do, kindly ask me via the comment section.
Inheritance simply means that a new class known as the child class inherits all the attributes and methods of an existing class known as the parent class. The child class can also define new attributes and methods for itself.
Some programmers refer the child class as a sub class and the parent class as the super class. They all mean the same.
The picture below is a classic programming joke on object oriented programming.
Alright, let’s do some example.
I inherited some things from my dad, like complexion, height, emotions and even course of study.
So I will write a simple program to illustrate me inheriting these features from my dad.
I would love that you observe the below code snippet. The program is saved as class_inheritance_example.py in case you downloaded the code snippet of this tutorial.
1234567891011121314151617181920 | class Dad():def complexion(self):return "fair"def height(self):return "tall"def field_of_study(self):return "Chemical Engineering"class Godson(Dad):def hair_color(self):return "white"my_description = Godson()print( "Godson is",my_description.complexion(),"in complexion")print( "Godson is studying",my_description.field_of_study())print( "Godson hair color is",my_description.hair_color()) |
When you run the program above, you will get this.
The Dad class has the following functions/methods which are complexion, height, and field of study. This methods return the following values respectively, fair, tall, and chemical engineering.
This line of code, “class Godson(Dad):” means that Godson is a subclass of Dad. That is, it tells Python that the Godson class( subclass) should inherit all the methods of the superclass(Dad).
Whenever you define a class, you must include at least one method. Since I don’t have any method to include in the Godson class, I used the pass statement. This prevents error when I run the program.
The pass statement can also be replaced with a method. The code snippet below is a modification of the class_inheritance_example.py program.
1234567891011121314151617 | class Dad():def complexion(self):return "fair"def height(self):return "tall"def field_of_study(self):return "Chemical Engineering"class Godson(Dad):def hair_color(self):return "white"my_description = Godson()print( "Godson hair color is",my_description.hair_color()) |
when the run the code snippet above, you will get this.
Godson hair color is white
Multiple Inheritance
A sub class can inherit the methods of two or more classes.
To illustrate this, I will add another class Mom to the class_inheritance_example.py program.
Here is the new modification. The program below is saved as multiple_class_inheritance.py in case you downloaded the code snippet for this tutorial.
12345678910111213141516171819202122 | class Dad():def complexion(self):return "fair"def height(self):return "tall"def field_of_study(self):return "Chemical Engineering"class Mom():def occupation(self):return "entreprenuer"class Godson(Dad,Mom):def hair_color(self):return "white"my_description = Godson()print( "Godson is an", my_description.occupation()) |
When you run the above code, you will get the following result.
This line of code “class Godson(Dad,Mom):” simply tells Python that the Godson class(sub class) should inherit all the methods of the Dad and Mom class which are the super class.
Class inheritance with the __init__ method
So far we have seen a classes without the __init__ method inheriting the methods of a super class.
What if the class has the __init__ method?
I will illustrate this with an example. The program below is saved as modified_class_inheritance.py in case you downloaded the code snippet for this tutorial.
1234567891011121314151617181920212223242526272829303132333435 | class Dad():def __init__(self,complexion,field_of_study):self.complexion = complexionself.field_of_study = field_of_studydef set_complexion(self,complexion):self.complexion = complexiondef set_field_of_study(self,field_of_study):self.field_of_study = field_of_studydef get_complexion(self):return self.complexiondef get_field_of_study(self):return self.field_of_studyclass Godson(Dad):def __init__(self,complexion,field_of_study,hair_color):Dad.__init__(self,complexion,field_of_study)self.hair_color = hair_colordef set_hair_color(self,hair_color):self.hair_color = hair_colordef get_hair_color(self):return self.hair_colormy_description = Godson("fair","Chemical Engineering", "white")print( "Godson hair color is",my_description.get_hair_color())print( "Godson is studying",my_description.get_field_of_study())print( "Godson hair color is",my_description.get_hair_color()) |
Like as I’ve said before, “class Godson(Dad):” tells Python that the sub class(Godson) should inherit all the methods in the super class(Dad).
Take a look at this line of code below:
def __init__(self,complexion,field_of_study,hair_color):
Did you noticed that the instance variables(complexion and field_of_study) of the class Dad were included.
This is because I inherited all these from my dad. The last parameter(instance variable) which is hair_color was not inherited from my dad. In fact, that’s what makes me different from my dad.
Also take a look at this line of code below:
Dad.__init__(self,complexion,field_of_study)
The above code simply calls the Dad’s __init__ method. The self parameter is included because when the method is executed, it initializes the complexion, field_of_study attributes.
How to Override a Method from the Super Class
In Python, you can override a method in the super class that no longer describes the sub class.
To do this, simply define a method in the sub class with the same name as the method in the super class that you want to override.
I will illustrate how to override a method from the super class in the code snippet below. The program below is saved as overriding_example.py in case you downloaded the code snippet for this tutorial.
1234567891011121314151617 | class Mom():def complexion(self):return "dark"def occupation(self):return "entrepreneur"class Godson(Mom):def complexion(self):return "fair"description = Godson()print("Godson is",description.complexion(),"in complexion.")print("Godson is an",description.occupation()) |
when you run the above code snippet, you will get this as a result:
Godson is fair in complexion.
Godson is an entrepreneur
Am sure you won’t have any problem understanding the overriding_example.py program.
We are able to override the method of a super class because of a simple concept known as Polymorphism.
The idea behind polymorphism is that,
a method in a sub class can have the same name as the name in the super class.
Object-Oriented Programming Terms in Python.
Below is the definition of technical terms used in this tutorial.
We have come to the end of this tutorial.
Please if you have any questions or contributions, please leave it in the comment section.
Thanks for reading. If you enjoyed this tutorial, hit the share button. It would mean a lot to me and it helps other people to see the tutorial.
Original article and pictures take coolpythoncodes.com site
Комментариев нет:
Отправить комментарий