🌍 Python Programming · subject
Python Programming Object-Oriented Programming Syllabus
The Object-Oriented Programming syllabus for Python Programming in full: 5 chapters and 18 topics, every one listed below, plus 50 Object-Oriented Programming flashcards with answers.
Object-Oriented Programming syllabus: all 5 chapters
Expand any chapter to see its topics and sub-topics.
-
Classes and Objects
4 topics- Defining Classes
- Instance Attributes and Methods
- The __init__ Constructor and self
- Class vs Instance Variables
-
Inheritance and Polymorphism
4 topics- Single and Multiple Inheritance
- Method Overriding and super()
- Method Resolution Order (MRO)
- Polymorphism and Duck Typing
-
Encapsulation and Properties
3 topics- Public, Protected and Private Members
- Property Decorators and Getters/Setters
- Name Mangling
-
Special and Magic Methods
3 topics- String Representation
- Operator Overloading
- Comparison and Hashing Methods
-
Advanced Class Concepts
4 topics- Class Methods and Static Methods
- Abstract Base Classes
- Dataclasses
- Slots and Memory Optimization
Python Programming Object-Oriented Programming flashcards — 50 questions with answers
In Python, what keyword defines a class, and what is the conventional naming style for class names?
The `class` keyword defines a class. Class names conventionally use CapWords/PascalCase (e.g., `BankAccount`).
What is an instance attribute, and where is it typically created?
An instance attribute is data unique to each object, stored on the instance itself. It is typically created by assigning to `self.name` inside `__init__` (or any method).
What is the purpose of the `__init__` method, and is it technically a constructor?
`__init__` initializes a newly created instance's state. It is not the true constructor; `__new__` creates the object, and `__init__` only initializes it after creation.
What does the `self` parameter refer to, and how is it passed?
`self` refers to the current instance. It is passed automatically as the first argument when you call a method on an object (e.g., `obj.method()` passes `obj` as `self`).
What is the key difference between a class variable and an instance variable?
A class variable is shared by all instances (defined in the class body), while an instance variable is unique per object (assigned via `self`). Assigning to `self.x` shadows a class variable of the same name for that instance.
If a class variable is a mutable object (e.g., a list) shared across instances, what common bug occurs?
All instances share the same object, so mutating it via one instance (e.g., `self.items.append(x)`) affects every instance. Mutable defaults should be created per-instance in `__init__`.
What is an instance method versus how it differs from accessing an attribute?
An instance method is a function defined in a class that takes `self` as its first parameter and operates on instance data; it is called as `obj.method(args)`.
How do you define single inheritance in Python?
List the parent class in parentheses after the class name: `class Child(Parent):`. `Child` inherits Parent's attributes and methods.
What is multiple inheritance, and what is its syntax?
Multiple inheritance lets a class inherit from more than one base: `class C(A, B):`. `C` combines the members of A and B, resolved by the MRO.
What does method overriding mean?
Method overriding is redefining a method in a subclass with the same name as one in the parent, so the subclass version replaces the parent's for instances of the subclass.
What does `super()` do, and give a common use in `__init__`.
`super()` returns a proxy that delegates to the next class in the MRO. It is commonly used to call the parent initializer: `super().__init__(...)` to run the base class setup.
What is the Method Resolution Order (MRO)?
The MRO is the ordered list of classes Python searches to find an attribute or method. For new-style classes it is computed by the C3 linearization algorithm.
How can you inspect a class's MRO?
Use `ClassName.__mro__`, `ClassName.mro()`, or `help(ClassName)`. It lists classes from the class itself up through its bases to `object`.
What guarantees does C3 linearization provide for the MRO?
C3 preserves the order that each class lists its bases (local precedence) and ensures a class always appears before its parents (monotonicity), producing a single consistent order or raising a TypeError if none exists.
What is polymorphism in the OOP sense?
Polymorphism lets objects of different classes respond to the same method call in their own way, so code can operate on a common interface without knowing concrete types.
What is duck typing?
Duck typing determines suitability by an object's methods/attributes rather than its type: 'if it walks like a duck and quacks like a duck, it's a duck.' Code works with any object that supports the required behavior.
By convention, what does a single leading underscore (e.g., `_value`) signal about a member?
It marks the member as protected/internal—an implementation detail not part of the public API. It is a convention only; Python does not enforce access restriction.
What is a public member in Python, and how is access control enforced?
A public member has no leading underscore and is part of the intended API. Python has no true access enforcement; 'private' and 'protected' are conventions plus name mangling for double-underscore names.
What does a double leading underscore (e.g., `__value`) trigger, and what is that feature called?
It triggers name mangling: inside a class `Foo`, `__value` becomes `_Foo__value`. This is called name mangling and helps avoid accidental name clashes in subclasses.
Name mangling: from outside the class, how would you access an attribute declared as `self.__secret` in class `Vault`?
As `obj._Vault__secret`. Name mangling rewrites `__secret` to `_Vault__secret`, so it is still accessible—just harder to hit accidentally.
Show the other 30 Object-Oriented Programming flashcards
What does the `@property` decorator do?
`@property` turns a method into a read-only computed attribute, letting you access it as `obj.attr` (no parentheses) while running getter logic behind the scenes.
How do you define a setter for a property named `x`?
Define the getter with `@property`, then a method decorated `@x.setter`, both named `x`: assigning `obj.x = value` invokes the setter. A `@x.deleter` similarly handles `del obj.x`.
What is the main advantage of using properties over public attributes?
Properties let you add validation or computed logic later without changing the attribute-access syntax, preserving the public interface while controlling get/set/delete behavior.
Which dunder method controls `str(obj)` and `print(obj)`, and what is its intent?
`__str__` controls `str()`/`print()`. Its intent is a readable, user-friendly representation. If `__str__` is absent, Python falls back to `__repr__`.
Which dunder method controls `repr(obj)`, and what is its intended goal?
`__repr__` controls `repr()` and the interactive echo. Its goal is an unambiguous, developer-oriented string—ideally one that could recreate the object, e.g., `Point(1, 2)`.
If only one of `__str__` or `__repr__` is defined, which should you define, and why?
Define `__repr__`. `__str__` falls back to `__repr__` when missing, so a single `__repr__` covers both `str()` and `repr()`.
What is operator overloading, and which method implements the `+` operator?
Operator overloading defines how operators behave for your objects via dunder methods. `a + b` calls `a.__add__(b)` (with `b.__radd__(a)` as fallback).
Match these operators to their dunder methods: `-`, `*`, `==`, `<`.
`-` → `__sub__`, `*` → `__mul__`, `==` → `__eq__`, `<` → `__lt__`.
What does the `__eq__` method define, and what is its default behavior if undefined?
`__eq__` defines behavior for `==`. Without it, equality defaults to identity comparison (`is`), i.e., objects are equal only if they are the same object.
What happens to `__hash__` when you define `__eq__` on a class, and why does it matter?
Defining `__eq__` sets `__hash__` to `None`, making instances unhashable (unusable as dict keys or set members). You must define `__hash__` explicitly to restore hashability.
What contract must equal objects satisfy regarding hashing?
If `a == b` then `hash(a) == hash(b)`. Objects that compare equal must have equal hashes; otherwise they break dict/set behavior.
What does the `functools.total_ordering` decorator provide?
Given `__eq__` plus one of `__lt__`, `__le__`, `__gt__`, or `__ge__`, `total_ordering` fills in the remaining rich comparison methods automatically.
What is a class method, how is it declared, and what is its first parameter?
A class method is declared with `@classmethod`; its first parameter is `cls` (the class, not the instance). It is often used for alternative constructors, e.g., `cls(...)`.
What is a static method, how is it declared, and what special parameters does it receive?
A static method is declared with `@staticmethod`; it receives neither `self` nor `cls`. It is a plain function grouped in the class namespace for organizational purposes.
Compare instance method, class method, and static method by their implicit first argument.
Instance method → receives `self` (the instance); class method → receives `cls` (the class); static method → receives no implicit argument.
Why is `@classmethod` preferred over hardcoding the class name in an alternative constructor?
Using `cls(...)` respects inheritance: a subclass calling the alternative constructor gets an instance of the subclass, whereas hardcoding the base class name would not.
What is an Abstract Base Class (ABC), and which module provides the tooling?
An ABC defines an interface that cannot be instantiated directly and requires subclasses to implement certain methods. The `abc` module provides `ABC`/`ABCMeta` and `@abstractmethod`.
How do you declare an abstract method, and what happens if a subclass doesn't implement it?
Decorate it with `@abstractmethod`. If a concrete subclass fails to override all abstract methods, attempting to instantiate it raises `TypeError`.
What is the standard way to make a class abstract using the `abc` module?
Inherit from `abc.ABC` (or set `metaclass=abc.ABCMeta`) and mark required methods with `@abstractmethod`. Instantiating the class directly then raises `TypeError`.
What does the `@dataclass` decorator generate automatically?
From `dataclasses`, `@dataclass` auto-generates `__init__`, `__repr__`, and `__eq__` (and optionally ordering and `__hash__`) based on class-level annotated fields.
In a dataclass, why must mutable default values use `field(default_factory=...)`?
A bare mutable default (e.g., `x: list = []`) would be shared across instances and raises a ValueError in dataclasses. `field(default_factory=list)` creates a fresh object per instance.
What does `@dataclass(frozen=True)` do?
It makes instances immutable: attribute assignment after creation raises `FrozenInstanceError`. Frozen dataclasses also become hashable, so they can be used in sets/dict keys.
What does the `order=True` parameter add to a dataclass?
It generates the comparison methods `__lt__`, `__le__`, `__gt__`, and `__ge__`, which compare instances field-by-field as a tuple of their values.
What is the purpose of `__slots__` in a class?
`__slots__` declares a fixed set of allowed attributes, preventing creation of a per-instance `__dict__`. This reduces memory usage and can speed up attribute access.
Name two consequences of defining `__slots__` on a class.
(1) You cannot add attributes not listed in `__slots__` (raises AttributeError); (2) instances have no `__dict__` by default, so dynamic attributes and (unless declared) `__weakref__` are unavailable.
When does `__slots__` give the biggest memory benefit?
When you create very large numbers of small, fixed-shape instances—eliminating the per-instance `__dict__` saves significant memory across many objects.
What is the difference between `__str__` fallback and `__repr__` in a container like a list?
When you print a list, its elements are shown using their `__repr__`, not `__str__`. So a list of objects displays each element's `repr` regardless of `__str__`.
Which dunder methods implement the six rich comparisons?
`__lt__` (<), `__le__` (<=), `__gt__` (>), `__ge__` (>=), `__eq__` (==), and `__ne__` (!=).
What is the difference between `isinstance()` and `type() ==` for type checking, especially with inheritance?
`isinstance(obj, Cls)` is True for instances of `Cls` or any subclass, respecting inheritance; `type(obj) == Cls` is True only for the exact class, ignoring subclasses. `isinstance` is generally preferred.
In multiple inheritance, when a diamond hierarchy exists (D inherits B and C, both inheriting A), why does cooperative `super()` matter?
C3 linearization ensures A is visited only once (after both B and C). Using `super().__init__()` in each class lets the MRO chain each initializer exactly once, avoiding duplicate or skipped base initialization.
Python Programming Object-Oriented Programming FAQ
What is in the Python Programming Object-Oriented Programming syllabus?
Python Programming Object-Oriented Programming is split into 5 chapters: Classes and Objects, Inheritance and Polymorphism, Encapsulation and Properties, Special and Magic Methods and Advanced Class Concepts. Together they contain 18 topics.
How many chapters are in Python Programming Object-Oriented Programming?
5 chapters, containing 18 topics. The largest chapter is Classes and Objects, with 4 topics.
Are there flashcards for Python Programming Object-Oriented Programming?
Yes — a 50-card Object-Oriented Programming deck, printed in full in the flashcards section of this page and available in the Examius app with spaced repetition. The free plan covers one exam of your choice, including its flashcards; Examius Pro, a one-time purchase, unlocks every other exam and deck.