Skip to main content

1. Classes and Instances

Object-Oriented Programming (OOP) is a paradigm that groups related data (attributes) and behaviors (methods) into reusable blueprints called classes. An individual object built from a class is an instance. A class is a blueprint for creating objects. In this example, we create a simple Student class with two attributes (name and age) and two methods (introduce() and study()).

Output

Key Concepts

  • Class: Student
  • Object: student1
  • Attributes: name, age
  • Methods: introduce(), study()
  • Constructor: __init__() initializes the object’s attributes.
This example demonstrates:
  • Defining a class using class
  • Initializing attributes using __init__()
  • Creating methods inside a class
  • Creating an object
  • Accessing object attributes
  • Calling object methods

2. Attributes and Methods

Classes can hold both data and code. These are categorized into instance-level and class-level members.

Instance Methods

Functions inside a class that operate on a specific instance of that class. They must accept self as the first argument.

Class Attributes & Methods (@classmethod)

  • Class Attributes: Variables shared by all instances of a class.
  • Class Methods: Decorated with @classmethod, they accept cls (the class itself) instead of self. They are used for factory methods or modifying class-level state.

Static Methods (@staticmethod)

Decorated with @staticmethod, these do not accept self or cls. They act like normal helper functions grouped inside the class namespace.

Type Checking (type vs isinstance)

  • type(obj) returns the exact class/type of an object.
  • isinstance(obj, ClassName) checks if an object is an instance of a class or any subclass (preferred for polymorphism).

3. Class Inheritance

Inheritance allows a new class (child/subclass) to inherit attributes and methods from an existing class (parent/superclass).

Passing Arguments Along with Class Name in Inheritance

You can pass custom configuration arguments directly inside the class declaration parentheses next to the parent class name. This is done by implementing the special class method __init_subclass__ in the parent class.

What happens when this code is run?

  1. Class-level Interception: When Python compiles and executes the class definition of UserProfile, it notices that DatabaseModel defines a __init_subclass__ method.
  2. Hook Execution: Instead of just creating the UserProfile class normally, Python automatically calls DatabaseModel.__init_subclass__(UserProfile, table="users").
  3. Property Assignment: The method receives the newly created subclass as cls and the keyword argument table. It then sets cls.table_name = "users". This operates at class-definition time (import time), long before any instances of UserProfile are created.

Why do we need this pattern?

  • Declarative Configuration: In ORM libraries (like SQLAlchemy or SQLModel) or API frameworks, it is common to define database tables or routes declaratively. This pattern allows subclasses to configure themselves during creation.

4. Encapsulation

Encapsulation restricts direct access to an object’s internal state to prevent accidental modifications.

Private & Protected Fields

  • Protected (_name): A convention suggesting the field is for internal/subclass use. Python does not enforce this.
  • Private (__pin): Triggers Name Mangling (_ClassName__pin), causing Python to raise an AttributeError if accessed directly.

5. Properties

Property Getters & Setters (@property)

Properties allow you to define methods that behave like attributes, which is useful for validating data when reading or writing a field.

6.Abstract Classes

Python provides built-in mechanisms to inspect objects at runtime, define interfaces/abstract classes, and customize how arguments are passed during class inheritance.

Abstract Base Classes (ABCs)

The abc module allows you to define abstract classes that cannot be instantiated and force subclasses to implement specific methods.

7. Introspection

Introspection: __dict__ and __annotations__

  • __dict__: A dictionary containing the namespaces of an object (its attributes and values).
  • __annotations__: A dictionary containing type annotations defined on the class or function.