Object-oriented programming¶
Fanny Ducel (CC BY-NC-SA) -- 2024
This notebook corresponds to your last lecture and covers:
- Objects
It is inspired from different sources:
About the exam¶
- Nov 18th, from 13h30-15h30
- Multiple-Choice Questions (only 1 answer to pick per question)
- Similar to Wooclap questions: "theoritical questions" and questions on some code (what is it doing, what's the problem, what happens at line X, ...)
About last week¶
- Questions?
- Don't forget to import matplotlib with:
matplotlib.pyplot
- Try to make your code easy to read: use different cells (better than to have one huge scary cell that takes a long time to run)
Objects¶
Python is an object oriented language. It means everything is an object.
Objects have properties and methods. Objects are instances of a class.
3 key properties to objects:¶
- identity: an object has a unique identity
- state: an object has properties/attributes that characterize it
- behavior: an object has methods (= functions defined within a class)
Classes¶
To create objects, we uses classes (= object constructors). A class is like a template for objects.
When you create a new class, you create a new type of object.
# Let's create a class!
class Dog: # class is the keyword to define a class
#(like "def" for functions), we typically use a capitalized name
def __init__(self, name):
self.name = name # name is an attribute
#(it will constitute the identity of an instance)
# Let's create an instance of our class (= an object)
rex = Dog("Rex")
print(rex.name)
Rex
# You can create as many objects as you want with one class
dog2 = Dog("Médor")
print(dog2.name)
Médor
We can then check the type of an instance, or check if they're an instance of a given type:
print(type(rex))
print(isinstance(rex, Dog))
<class '__main__.Dog'> True
A word about the __init__()
function¶
All classes have an __init__()
function. It is always (automatically) executed when the class is used to create a new object.
The __init__()
function is used to assign values to object properties, or other operations that are necessary to create the object.
A word about the self
parameter¶
It refers to the current instance of the class, it is used to access variables that belong to the class.
It has to be the first parameter of any function in the class (including init).
Attributes¶
# Let's add more attributes to the class
class Dog:
def __init__(self, name, color, age): # we have to add the new
#attribute here as well
self.name = name
self.color = color
self.age = age
# Now when we create an instance, we should specify its color too
rex = Dog("Rex", "brown", 4)
print(rex.name, rex.color, rex.age)
Rex brown 4
# Let's modify attributes!
rex.color = "black"
print(rex.color)
# You can also delete attributes (or objects) with the "del" keyword
# del rex.color
# print(rex.color)
del rex
print(rex.name)
black
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[5], line 11 6 # You can also delete attributes (or objects) with the "del" keyword 7 # del rex.color 8 # print(rex.color) 10 del rex ---> 11 print(rex.name) NameError: name 'rex' is not defined
Translated with Google Translation from https://www.expertpython.fr/post/la-programmation-orient%C3%A9e-objet-en-python
Let's reproduce this kind of representation for our Dog class!¶
Class variables vs. instance variables¶
If an attribute is defined outside of the __init__()
function, it will be shared by all instances of the class. It is called a class variable.
On the contrary, instance variables are defined inside the __init__()
function and will change depending on the instance.
⚠️ Make sure to only use class variables when you want all instances of your class to share the exact same property.
class Dog:
species = "dog" # this attribute will be the same for all instances of the class ( = **class variable**)
def __init__(self, name, color): # the attributes defined in this function are **instance variables**
self.name = name
self.color = color
rex = Dog("Rex", "Brown")
medor = Dog("Médor", "Black")
print(rex.species, medor.species)
dog dog
Translated with Google Translation from https://www.expertpython.fr/post/la-programmation-orient%C3%A9e-objet-en-python
Let's reproduce this kind of representation for our Dog class!¶
🥳 Exercise: create a class "Cat". It should contain the attributes name, color and whether or not it's sociable. Then, create different cat instances.
class Cat:
def __init__(self, name, color, sociable):
self.name = name
self.color = color
self.sociable = sociable
cat1 = Cat("Felix", "black and white", True)
print(cat1.sociable)
False
Methods¶
Now that we created classes with attributes, we want our instances to be able to perform actions. So we need to define methods = functions within the class. Most of the times, methods are verbs.
class Dog:
species = "dog"
def __init__(self, name, color):
self.name = name
self.color = color
self.tricks = []
def make_noise(self): #as mentioned before, the first parameter
#of the function has to be "self"
return "Woof"
def add_tricks(self, trick):
self.tricks.append(trick)
def do_tricks(self):
for trick in self.tricks:
print(self.name, "does a", trick, "trick")
return "Good doggo!"
medor = Dog("Médor", "brown")
medor.add_tricks("roll over")
print(medor.tricks)
print(medor.make_noise())
print(medor.do_tricks())
['roll over'] Woof Médor does a roll over trick Good doggo!
rex = Dog("Rex", "black")
print(rex.tricks) # What is going on here?
[]
🥳 Exercise: Add methods to your class "Cat" and try them out:
- a method "introduce" which prints the cat's name and color
- a method "make_noise" with the sound that cats produce in your native language (e.g. "Meow" in English)
- a method "pet" which indicates whether or not you can pet the cat based on its sociability
class Cat:
def __init__(self, name, color, sociable):
self.name = name
self.color = color
self.sociable = sociable
cat1 = Cat("Felix", "black and white", True)
print(cat1.sociable)
class Cat:
def __init__(self, name, color, sociable):
self.name = name
self.color = color
self.sociable = sociable
def introduce(self):
return f"My name is {self.name}, and I am a {self.color} cat."
def make_noise(self):
return "Meow"
def pet(self):
if self.sociable:
return "You can pet the cat"
#return "Good cat"
else:
return "Oops, you can't pet the cat"
#return "Poor cat"
cat1 = Cat("Felix", "black and white", True)
print(cat1.sociable)
print(cat1.introduce())
print(cat1.make_noise())
print(cat1.pet())
True My name is Felix, and I am a black and white cat. Meow You can pet the cat
class Cat:
def __init__(self, name, color, sociable):
self.name = name
self.color = color
self.sociable = sociable
def introduce(self):
return f"{self.name} is a {self.color} cat"
def make_noise(self):
return "Meow"
def pet(self):
if self.sociable:
return f"You can pet {self.name}!"
else:
return f"If you try to pet {self.name}, it may scratch you..."
Inheritance¶
You probably noticed that the Dog and Cat classes have some common properties and methods. Instead of having multiple identical properties and methods in different classes, we use the notion of inheritance to create a parent class.
A parent class (or base class) will be inherited from.
A child class (or derived class) will inherit from its parent class.
# Let's create a parent class for Dog and Cat that include
#the common properties and methods
class Animal:
def __init__(self, name, color):
self.name = name
self.color = color
def make_noise(self):
return "?"
def introduce(self):
return f"{self.name} is {self.color}"
# As you can see, the syntax is the same as before
# Now, let's create the children classes
class Dog(Animal): # we have to indicate the parent class here
def __init__(self, name, color):
super().__init__(name, color) # We inherit these attributes
#from the Animal class
# Animal.__init__(self, name, color) # Alternative way (less used)
self.noise = "Woof"
self.tricks = []
def make_noise(self):
return self.noise
def add_tricks(self, trick):
self.tricks.append(trick)
def do_tricks(self):
for trick in self.tricks:
print(self.name, "does a", trick, "trick")
return "Good doggo!"
kutta = Dog("Kutta", "grey")
print(kutta.make_noise())
kutta.add_tricks("shake hands")
print(kutta.do_tricks())
print(kutta.introduce())
Woof Kutta does a shake hands trick Good doggo! Kutta is grey
🥳 Exercise: Adapt the Cat class to make it a child class of Animal
class Animal:
def __init__(self,name,color):
self.name = name
self.color = color
def make_noise(self):
return "?"
def introduce(self):
return f"{self.name} is {self.color}"
class Cat(Animal):
def __init__(self,name,color):
super().__init__(name,color)
...
🥳 Exercise: Create a Calculator class that can do additions, substractions, multiplications and divisions.
#TODO
text = "This is a sentence a good sentence Count how many times the different words are present. How many times"
# vocabulary = {"a": 2, "this":1}
new_text = text.split()
vocabulary = {}
for word in new_text:
if word not in vocabulary:
vocabulary[word] = 1
else:
vocabulary[word] += 1
print(vocabulary)
{'This': 1, 'is': 1, 'a': 2, 'sentence': 2, 'good': 1, 'Count': 1, 'how': 1, 'many': 2, 'times': 2, 'the': 1, 'different': 1, 'words': 1, 'are': 1, 'present.': 1, 'How': 1}
age = 50
if age < 18 :
print("You are a minor")
elif age > 70:
print("You are an elderly")
else:
print("Okay")
Okay
That's all for today! That was your last Python lecture! Good job!¶
Questions?