Object-Oriented Programming in Python: An Example Guide
ALX GUIDED - 0x08. Python - More Classes and Objects
Intro.
The basic concepts of object-oriented programming (OOP) are the same across different programming languages, including Python. However, the syntax and implementation details of OOP in Python can differ from other languages.
In Python, everything is an object, and classes are used to define new types of objects. Python supports the following OOP concepts: Encapsulation - Inheritance - Polymorphism - Abstraction
Python also supports special methods that allow classes to define their own behaviour for built-in functions and operators. These special methods are denoted by double underscores (e.g., __init__
, __str__
, __add__
, etc.) and are also known as magic methods.
First-class everything:
In Python, the concept of "first-class everything" means that all types of objects are treated equally and can be manipulated and passed around in the same way. Specifically, this means that:
Functions, Classes, Modules can be assigned to variables, passed as arguments to other functions, and returned as values from functions.
What is the difference between a class and an object or instance ?
a class is a template or blueprint for creating objects, while an object or instance is a specific instance of a class with its own set of attribute values. When you create an object, you are creating a specific instance of that class that has its own unique identity and behaviour.
look at this example:
__init__:
In Python, __init__
is a special method that is used to initialize the attributes of an object when it is created. The __init__
method is called automatically when an instance of a class is created, and it can take any number of parameters, but the first parameter is always self
, which refers to the instance being created.
Here's an example of how to use the __init__
method in a class:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
Self:
In Python, "self" is a special keyword that is used as the first parameter in a method or function definition within a class. It refers to the instance of the class that the method or function is being called on.
For example, consider the following class definition:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def say_hello(self):
print("Hello, my name is", self.name, "and I am", self.age, "years old.")
In this class, the __init__
method is called when a new instance of the Person
class is created, and takes two parameters, name
and age
. The self
parameter is used to refer to the instance of the class that is being created, and is used to set the name
and age
attributes of that instance.
The say_hello
method takes no additional parameters beyond self
, and uses the self
keyword to access the name
and age
attributes of the instance it is being called on.
What are and how to use public, protected and private attributes ?
Attribute versus Property:
The key difference between an attribute and a property is that the property provides a way to control how the attribute is accessed and modified, while the attribute can be accessed and modified directly. In this example, the greeting
property provides a way to format and return the name
attribute as a string, while the name
attribute can be accessed and modified directly.
Pythonic getters and setters: 💊
Using properties with getter and setter methods is a Pythonic way to encapsulate attributes and provide controlled access to them, while still allowing them to be accessed and modified like regular attributes.
__str__ and __repr__
methods:
The main difference between __str__
and __repr__
is that __str__
is intended to provide a human-readable string representation of an object, while __repr__
is intended to provide an unambiguous string representation of an object that can be used to recreate it.
Object attribute Versus a class attribute:
Object attributes are specific to each instance of a class. They are defined in the __init__
method, Class attributes, on the other hand, are shared by all instances of a class. They are defined directly in the class, outside of any method.
When a class attribute is accessed or modified, it affects all instances of the class.

Class and static methods:
A class method is a method that is :
bound to the class and not the instance of the class.
Defined using the
@classmethod
decoratorTake the class itself as the first argument.
Can be used to access or modify class-level data, or to create new instances of the class.
Here's an example of a class method:

Person
class has an alternative constructor from_birth_year
, which takes the name
and birth_year
One common use case for class methods is to create alternative constructors for a class. If we have a class that can be initialized in multiple ways, we can define class methods that provide alternate ways to create instances of the class.
Static Method:
A static method, on the other hand, is a method that is bound to the class and not the instance of the class, but does not take the class itself as the first argument. Static methods are defined using the @staticmethod
decorator and do not have access to either the class or the instance of the class. Static methods can be used to encapsulate functionality that does not depend on either the class or the instance of the class.
Bind an attribute to a class or object:
In Python, you can dynamically create new attributes for existing instances of a class by simply assigning a value to a new attribute name. For example:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
person1 = Person("Alice", 30)
person2 = Person("Bob", 25)
person1.gender = "female"
person2.gender = "male"
print(person1.gender) # Output: female
print(person2.gender) # Output: male
To bind an attribute to a class, you can either assign a value to the attribute name directly within the class definition, or you can use the built-in setattr
function to dynamically set the attribute value at runtime:
class Person:
species = "human" # Binding attribute to the class
person1 = Person("Alice", 30)
setattr(Person, "gender", "female") # Dynamically binding attribute to the class
__del__
and __doc__
is a special method in Python that is called when an object is about to be destroyed (i.e., garbage collected) by the Python interpreter. __del__
is used to define a custom action that should be performed when an object is no longer needed.
__doc__
is a special attribute in Python that is used to store the docstring (i.e., documentation string) of a module, class, function, or method.
print(Person.__doc__) # Output: A class that represents a person.
Tips:
In Python, name mangling is a technique that prefixes the attribute name with a double underscore (
__
) when it is accessed outside of its class, so we use it if class name needed in output like :{'_Employer__salary': 25620}
Using double underscores (
__
) in the__init__
method is not necessary for name mangling. Name mangling is primarily used to prevent accidental name clashes between attributes of different classes, and it is applied to attributes with double underscores when accessed outside the class.The
str
function is a built-in Python function that converts its argument to a string. if the argument isself._width
, for example, which is assumed to be an integer. Thestr
function converts this integer to a string, which can be used in string concatenation or formatting.str(self._width)
is a Python expression that converts the value of theself._width
attribute to a string.The
__del__
method is a special method in Python that is called when an object is about to be destroyed or garbage-collected. It is used to perform any necessary clean-up actions before the object is removed from memory.The
__del__
method takes no arguments, and its return value is ignored. Here's an example of how to use the__del__
method:class MyClass: def __init__(self, name): self.name = name
def __del__(self): print(f"Deleting {self.name}...")obj1 = MyClass("Object 1") obj2 = MyClass("Object 2")
del obj1self.attribute
versusclass.attribute like :
Both are attributes of the
a
class, but they are used in different ways.self.attribute
is an instance attribute, which means that it belongs to individual instances of thethe
class. Each instance can have its ownattribute
value, which can be set and changed independently.Example :
5. You can check whether an object is an instance of a class using the built-in
isinstance
function in Python.To check if an object
obj
is an instance of the class, you can use theif
isinstance(obj, Rectangle): # obj is an instance of Rectangle else: # obj is not an instance of Rectangle
You may want to see :