The
The
Example: Using
Here, the
super() FunctionThe
super() function allows a child class to call the constructor or methods of its parent class. This is useful when you want to extend the functionality of a parent class without duplicating code.Example: Using
super()class Animal:
def __init__(self, species):
self.species = species
def sound(self):
print("Some generic animal sound.")
# Child class inheriting from Animal class
class Dog(Animal):
def __init__(self, name, species="Dog"):
super().__init__(species) # Calling parent class constructor
self.name = name
def sound(self):
super().sound() # Calling parent class method
print(f"{self.name} barks!")
dog1 = Dog("Buddy")
dog1.sound()
Here, the
super() function calls the parent classβs __init__() method to initialize the species attribute and also calls the parent class's sound() method from the child class.Method Overriding
Method overriding occurs when a subclass defines a method with the same name as a method in its parent class. The subclass's version of the method overrides the parent class's version.
Example: Method Overriding
In this example, the
Method overriding occurs when a subclass defines a method with the same name as a method in its parent class. The subclass's version of the method overrides the parent class's version.
Example: Method Overriding
class Animal:
def sound(self):
print("Some generic animal sound.")
class Dog(Animal):
def sound(self):
print("Bark!")
class Cat(Animal):
def sound(self):
print("Meow!")
dog = Dog()
cat = Cat()
dog.sound() # Output: Bark!
cat.sound() # Output: Meow!
In this example, the
sound() method is overridden in the Dog and Cat classes, replacing the generic version from the Animal class.π1
Multiple Inheritance
Python supports multiple inheritance, where a class can inherit from more than one parent class. This allows a class to inherit features from multiple classes.
Example: Multiple Inheritance
In this example, the
Python supports multiple inheritance, where a class can inherit from more than one parent class. This allows a class to inherit features from multiple classes.
Example: Multiple Inheritance
class Father:
def work(self):
print("Father is working.")
class Mother:
def cook(self):
print("Mother is cooking.")
class Child(Father, Mother):
def play(self):
print("Child is playing.")
child = Child()
child.work() # Inherited from Father class
child.cook() # Inherited from Mother class
child.play() # Child's own method
In this example, the
Child class inherits methods from both the Father and Mother classesPolymorphism in Python
Polymorphism allows objects of different classes to be treated as objects of a common superclass. It is implemented through method overriding, where different classes provide their own implementation of a method with the same name.
Example: Polymorphism
Here, both the
Polymorphism allows objects of different classes to be treated as objects of a common superclass. It is implemented through method overriding, where different classes provide their own implementation of a method with the same name.
Example: Polymorphism
class Bird:
def fly(self):
print("Bird is flying.")
class Airplane:
def fly(self):
print("Airplane is flying.")
def take_off(flying_object):
flying_object.fly()
bird = Bird()
airplane = Airplane()
take_off(bird) # Output: Bird is flying.
take_off(airplane) # Output: Airplane is flying.
Here, both the
Bird and Airplane classes have a fly() method, but the behavior is different for each class. The function take_off() can accept either a Bird or an Airplane and call their respective fly() method.π2
The
The
Example:
Example:
isinstance() and issubclass() FunctionsThe
isinstance() function checks if an object is an instance of a class or a subclass, while issubclass() checks if a class is a subclass of another class.Example:
isinstance()class Animal:
pass
class Dog(Animal):
pass
dog = Dog()
print(isinstance(dog, Dog)) # Output: True
print(isinstance(dog, Animal)) # Output: True
Example:
issubclass()class Animal:
pass
class Dog(Animal):
pass
print(issubclass(Dog, Animal)) # Output: True
Homework for Day 14
Create a class
Create a class
Employee with attributes name and salary. Create a subclass Manager that inherits from Employee and adds an attribute department. Use super() to initialize the parent class attributes in the subclass.Summary
In Day 14, we covered:
Inheritance, which allows a class to inherit properties and methods from another class, promoting code reuse.
The
Method overriding, which allows a child class to provide a specific implementation of a method that exists in its parent class.
Polymorphism, which allows objects of different classes to be treated as objects of a common superclass.
Multiple inheritance, where a class can inherit from more than one parent class.
Mastering inheritance and polymorphism allows you to write flexible, reusable, and maintainable code. These are powerful features in Pythonβs OOP model, and practicing them will help you build more structured applications. Keep experimenting with these concepts in your exercises and homework!
In Day 14, we covered:
Inheritance, which allows a class to inherit properties and methods from another class, promoting code reuse.
The
super() function, which allows a child class to call methods from its parent class.Method overriding, which allows a child class to provide a specific implementation of a method that exists in its parent class.
Polymorphism, which allows objects of different classes to be treated as objects of a common superclass.
Multiple inheritance, where a class can inherit from more than one parent class.
Mastering inheritance and polymorphism allows you to write flexible, reusable, and maintainable code. These are powerful features in Pythonβs OOP model, and practicing them will help you build more structured applications. Keep experimenting with these concepts in your exercises and homework!
π2π2
Day 15: Encapsulation, Abstraction, and Properties in OOP
Welcome to Day 15 of the "Noob to Pro in Python" course! Today, we will explore two other essential concepts in Object-Oriented Programming (OOP): Encapsulation and Abstraction. These concepts help to hide the internal workings of a class, provide controlled access to data, and enhance the security and maintainability of your code. We'll also cover how to use properties to manage attribute access.
Welcome to Day 15 of the "Noob to Pro in Python" course! Today, we will explore two other essential concepts in Object-Oriented Programming (OOP): Encapsulation and Abstraction. These concepts help to hide the internal workings of a class, provide controlled access to data, and enhance the security and maintainability of your code. We'll also cover how to use properties to manage attribute access.
Encapsulation
Encapsulation is the concept of bundling data (attributes) and methods that operate on that data within a class and restricting direct access to some of the classβs components. This helps protect the objectβs internal state and prevents outside interference.
Encapsulation in Python is achieved by making attributes private using name mangling. In Python, you can indicate that an attribute is private by prefixing its name with a double underscore
Example: Encapsulation with Private Attributes
Here,
Encapsulation is the concept of bundling data (attributes) and methods that operate on that data within a class and restricting direct access to some of the classβs components. This helps protect the objectβs internal state and prevents outside interference.
Encapsulation in Python is achieved by making attributes private using name mangling. In Python, you can indicate that an attribute is private by prefixing its name with a double underscore
__.Example: Encapsulation with Private Attributes
class BankAccount:
def __init__(self, balance):
self.__balance = balance # Private attribute
def deposit(self, amount):
if amount > 0:
self.__balance += amount
def withdraw(self, amount):
if 0 < amount <= self.__balance:
self.__balance -= amount
def get_balance(self):
return self.__balance
# Creating an object
account = BankAccount(1000)
# Trying to access the private attribute directly
# print(account.__balance) # This will raise an AttributeError
# Using public methods to interact with the balance
account.deposit(500)
account.withdraw(200)
print(account.get_balance()) # Output: 1300
Here,
__balance is a private attribute. It cannot be accessed directly from outside the class, but we can interact with it using public methods like deposit(), withdraw(), and get_balance().Name Mangling
Although Python uses name mangling to prevent direct access to private attributes, you can still access them using a special syntax. This feature is primarily used to avoid accidental access rather than as a strict security measure.
Example: Accessing Private Attributes with Name Mangling
This is not recommended in practice. Instead, access the data through methods provided by the class to maintain encapsulation.
Although Python uses name mangling to prevent direct access to private attributes, you can still access them using a special syntax. This feature is primarily used to avoid accidental access rather than as a strict security measure.
Example: Accessing Private Attributes with Name Mangling
class BankAccount:
def __init__(self, balance):
self.__balance = balance
account = BankAccount(1000)
# Accessing the private attribute via name mangling
print(account._BankAccount__balance) # Output: 1000
This is not recommended in practice. Instead, access the data through methods provided by the class to maintain encapsulation.
Abstraction
Abstraction is the concept of hiding the implementation details of a class and only exposing the essential features. It allows users to interact with objects at a higher level without knowing how the internal details work.
In Python, abstraction is typically implemented through abstract classes and interfaces (using the
Example: Abstract Class and Method
In this example:
Subclasses
You cannot instantiate the
Abstraction is the concept of hiding the implementation details of a class and only exposing the essential features. It allows users to interact with objects at a higher level without knowing how the internal details work.
In Python, abstraction is typically implemented through abstract classes and interfaces (using the
abc module). Abstract classes cannot be instantiated and are meant to define a blueprint for other classes to follow.Example: Abstract Class and Method
from abc import ABC, abstractmethod
class Shape(ABC): # Abstract base class
@abstractmethod
def area(self):
pass # Abstract method, must be overridden by subclasses
class Rectangle(Shape):
def __init__(self, length, width):
self.length = length
self.width = width
def area(self):
return self.length * self.width
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
rect = Rectangle(5, 3)
circle = Circle(4)
print(f"Rectangle area: {rect.area()}") # Output: Rectangle area: 15
print(f"Circle area: {circle.area()}") # Output: Circle area: 50.24
In this example:
Shape is an abstract class that defines an abstract method area().Subclasses
Rectangle and Circle implement the area() method as per their specific behavior.You cannot instantiate the
Shape class directly, but you can work with its subclasses.Properties in Python
Properties in Python provide a way to control access to instance attributes. They allow you to define methods that get or set the value of an attribute, but access it as if it were a regular attribute. This provides a clean interface to your class and ensures that any necessary validation or logic can be applied when accessing or modifying attributes.
Example: Using the
Here, the
Properties in Python provide a way to control access to instance attributes. They allow you to define methods that get or set the value of an attribute, but access it as if it were a regular attribute. This provides a clean interface to your class and ensures that any necessary validation or logic can be applied when accessing or modifying attributes.
Example: Using the
property() Decoratorclass Employee:
def __init__(self, name, salary):
self.__name = name
self.__salary = salary
# Getter method for 'salary'
@property
def salary(self):
return self.__salary
# Setter method for 'salary'
@salary.setter
def salary(self, value):
if value < 0:
raise ValueError("Salary cannot be negative.")
self.__salary = value
# Creating an Employee object
emp = Employee("Alice", 5000)
# Accessing the salary using the getter method
print(emp.salary) # Output: 5000
# Setting a new value for salary using the setter method
emp.salary = 6000
print(emp.salary) # Output: 6000
# Trying to set a negative salary (will raise an exception)
# emp.salary = -1000 # Raises ValueError: Salary cannot be negative.
Here, the
@property decorator turns the salary() method into a getter for the __salary attribute. The @salary.setter decorator allows controlled modification of the __salary attribute with validation.π1
Benefits of Encapsulation and Abstraction
Encapsulation protects data by restricting direct access and ensures that changes to attributes are controlled.
Abstraction hides the implementation details, allowing users to interact with objects at a higher level without needing to know the internal workings.
Properties in Python provide a clean and efficient way to manage access to class attributes, ensuring that data validation and other logic can be applied when necessary.
Encapsulation protects data by restricting direct access and ensures that changes to attributes are controlled.
Abstraction hides the implementation details, allowing users to interact with objects at a higher level without needing to know the internal workings.
Properties in Python provide a clean and efficient way to manage access to class attributes, ensuring that data validation and other logic can be applied when necessary.
Practice Exercises for Day 15
Exercise 1: Encapsulation
Create a class
Exercise 2: Abstraction
Create an abstract class
Exercise 3: Properties
Write a class
Exercise 4: Name Mangling
Create a class
Exercise 1: Encapsulation
Create a class
Person with private attributes name and age. Provide methods to get and set the values of these attributes while ensuring the age is always positive.Exercise 2: Abstraction
Create an abstract class
Appliance with an abstract method turn_on(). Implement two subclasses WashingMachine and Fridge, each overriding the turn_on() method to print a message.Exercise 3: Properties
Write a class
Temperature with a private attribute celsius. Use the property() decorator to create a getter and setter for celsius and a getter for fahrenheit, converting Celsius to Fahrenheit.Exercise 4: Name Mangling
Create a class
Car with private attributes brand and speed. Write methods to increase or decrease speed, ensuring the speed cannot be negative. Access the private attributes using name mangling.8. Summary
In Day 15, we covered:
- Encapsulation, which helps protect the internal state of objects by restricting direct access to certain attributes.
- Name mangling, which is used to create private attributes that canβt be accessed directly.
- Abstraction, which hides the implementation details and allows users to interact with a simplified interface.
- Abstract classes and methods, which define a common interface for different subclasses.
- Properties, which provide a clean way to manage attribute access and ensure proper validation.
Encapsulation and abstraction are critical principles for building robust, maintainable code, and properties provide a powerful mechanism to manage access to your classβs data. Keep practicing to solidify your understanding!
In Day 15, we covered:
- Encapsulation, which helps protect the internal state of objects by restricting direct access to certain attributes.
- Name mangling, which is used to create private attributes that canβt be accessed directly.
- Abstraction, which hides the implementation details and allows users to interact with a simplified interface.
- Abstract classes and methods, which define a common interface for different subclasses.
- Properties, which provide a clean way to manage attribute access and ensure proper validation.
Encapsulation and abstraction are critical principles for building robust, maintainable code, and properties provide a powerful mechanism to manage access to your classβs data. Keep practicing to solidify your understanding!
Discussion Group : https://t.me/+OdZTotLvM143ODI1
By mistake I missed some topicsπ
1. Decorators - Introduction, Use Cases
2. Python Built-in Functions (zip(), enumerate(), etc.)
3. Regular Expressions (regex)
Don't worry I will cover itπ
1. Decorators - Introduction, Use Cases
2. Python Built-in Functions (zip(), enumerate(), etc.)
3. Regular Expressions (regex)
Don't worry I will cover itπ
β€2
Day 16: Decorators - Introduction and Use Cases
Welcome to Day 16! Today, weβll dive into decorators, one of Pythonβs most powerful and useful features. By the end of this lesson, you will understand how decorators work, when to use them, and how they can improve your code.
Welcome to Day 16! Today, weβll dive into decorators, one of Pythonβs most powerful and useful features. By the end of this lesson, you will understand how decorators work, when to use them, and how they can improve your code.
π1
What is a Decorator?
A decorator in Python is a function that takes another function as an argument, adds some functionality to it, and returns it, without modifying the original functionβs structure.
Why Use Decorators?
Code Reusability: You can reuse the same code across multiple functions by applying the same decorator.
Separation of Concerns: Decorators allow you to separate different functionalities like logging, access control, etc.
Clean Code: By using decorators, you avoid cluttering the core functionality of your functions with extra responsibilities.
A decorator in Python is a function that takes another function as an argument, adds some functionality to it, and returns it, without modifying the original functionβs structure.
Why Use Decorators?
Code Reusability: You can reuse the same code across multiple functions by applying the same decorator.
Separation of Concerns: Decorators allow you to separate different functionalities like logging, access control, etc.
Clean Code: By using decorators, you avoid cluttering the core functionality of your functions with extra responsibilities.
π1