class Foo:
pass
print(type(Foo)) # <class 'type'>
print(type(Foo())) # <class '__main__.Foo'>
print(isinstance(Foo, type)) # True
Topics
20
Async Generators & Async Context Managers
Command-Line Interfaces (argparse)
Comprehensions & Generators
Concurrency (asyncio/threading/multiprocessing)
Data Types & Structures
Dataclasses & NamedTuples
Debugging & Profiling
Decorators
Descriptors & Properties
Exception Handling
File I/O & Context Managers
Functions & Scope
functools & Functional Programming Tools
Iterators & the Iterator Protocol
Logging
Magic Methods & Operator Overloading
Memory Management & Garbage Collection
Metaclasses & Class Customization
Modules & Packaging
Multiple Inheritance & MRO
Metaclasses & Class Customization
15 questions found
A metaclass is 'the class of a class' -- it defines how classes themselves are constructed, just as a class defines how instances are constructed. The default metaclass for all classes in Python is `type`; when you write `class Foo: pass`, Python actually calls `type('Foo', (), {})` behind the scenes to create the class object.
Real-world example
Understanding that classes are themselves objects (instances of type) explains why you can dynamically create classes at runtime using type() directly, without a class statement.
Multiple Inheritance & MRO;Descriptors & Properties
How do you create a class dynamically using type() with three arguments instead of a class statement?
Intermediatetype(name, bases, namespace) creates a new class object: name is the class's __name__ string, bases is a tuple of parent classes, and namespace is a dict of attributes and methods. This is exactly what the `class` keyword does internally, and calling type() directly lets you generate classes programmatically at runtime.
def greet(self):
return f'Hello, {self.name}'
Person = type('Person', (object,), {
'__init__': lambda self, name: setattr(self, 'name', name),
'greet': greet,
})
p = Person('Alice')
print(p.greet()) # Hello, Alice
Real-world example
An ORM framework dynamically generates model classes at import time using type(), building each class's attributes from a database schema definition rather than hand-writing every class.
Multiple Inheritance & MRO;Decorators
A custom metaclass subclasses `type` and overrides __new__ and/or __init__ to customize class creation itself -- for example, validating that subclasses implement required methods, auto-registering every subclass in a registry, or injecting attributes into every class using the metaclass. You use it via `class MyClass(metaclass=MyMeta):`.
class ValidatingMeta(type):
def __new__(mcs, name, bases, namespace):
if 'process' not in namespace and bases:
raise TypeError(f'{name} must implement process()')
return super().__new__(mcs, name, bases, namespace)
class Base(metaclass=ValidatingMeta):
def process(self): pass
class Bad(Base): # raises TypeError: missing process()
pass
Real-world example
A plugin framework uses a metaclass to automatically register every subclass of a Plugin base class into a global registry dict as soon as it's defined, enabling plugin discovery without explicit registration calls.
Multiple Inheritance & MRO;Decorators
How does __init_subclass__ provide a simpler alternative to metaclasses for many customization needs?
Intermediate__init_subclass__(cls, **kwargs) is a classmethod automatically called whenever a subclass is defined, letting you hook into subclass creation (validation, registration, attribute injection) without writing a full metaclass. It's simpler because you just define it in the base class, and Python 3.6+ handles the rest -- covering the majority of use cases that used to require a custom metaclass.
class Plugin:
registry = []
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
Plugin.registry.append(cls)
class MyPlugin(Plugin):
pass
print(Plugin.registry) # [<class 'MyPlugin'>]
Real-world example
A web framework uses __init_subclass__ on a base View class to automatically register every route handler subclass, replacing what older versions implemented with a metaclass.
Multiple Inheritance & MRO;Decorators
__class_getitem__(cls, item) is called when you subscript a class itself (not an instance), like `list[int]` or a custom `Container[str]`. It's primarily used to support type-hint syntax for generic classes without requiring inheritance from typing.Generic, returning a types.GenericAlias or custom object representing the parameterized type.
class Container:
def __class_getitem__(cls, item):
return f'{cls.__name__}[{item.__name__}]'
print(Container[int]) # 'Container[int]'
print(list[int]) # list[int] -- built-in generics support this too
Real-world example
A typed collections library implements __class_getitem__ so users can write `Stack[int]` for type hints and IDE autocompletion without needing to inherit from typing.Generic explicitly.
Data Types & Structures;Magic Methods & Operator Overloading
What role does the class namespace dict play during class creation, and how can __prepare__ customize it?
IntermediateDuring class body execution, Python populates a namespace mapping (by default a plain dict) with all the names defined in the class body (methods, class variables), which is then passed to the metaclass's __new__/__init__. A metaclass's __prepare__(mcs, name, bases) classmethod can return a custom mapping (like an OrderedDict or one that tracks definition order or rejects duplicate names) to control how that namespace behaves during class body execution.
class OrderedMeta(type):
@classmethod
def __prepare__(mcs, name, bases):
return {} # could return a custom ordered/tracking mapping
def __new__(mcs, name, bases, namespace):
cls = super().__new__(mcs, name, bases, namespace)
cls._field_order = list(namespace.keys())
return cls
Real-world example
An ORM metaclass uses __prepare__ with a custom mapping to preserve and later use the exact declaration order of model fields for generating a consistent database schema.
Data Types & Structures;Descriptors & Properties
How do abstract base classes (ABCs) use a metaclass to enforce that subclasses implement required methods?
AdvancedThe abc module's ABCMeta metaclass tracks methods decorated with @abstractmethod, and when you attempt to instantiate a class (not subclass, but instantiate) that hasn't overridden all abstract methods, ABCMeta's __call__ raises TypeError before __init__ even runs. This enforces an interface contract at instantiation time rather than only failing later when a missing method is actually called.
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self): ...
class Circle(Shape):
def __init__(self, r): self.r = r
def area(self): return 3.14159 * self.r ** 2
try:
Shape() # TypeError: Can't instantiate abstract class
except TypeError as e:
print(e)
Real-world example
A plugin interface defines an abstract PaymentProcessor base class with abstractmethod charge() and refund(), guaranteeing every concrete payment integration implements both before it can even be instantiated.
Multiple Inheritance & MRO;Exception Handling
What is the difference between a class decorator and a metaclass for customizing class behavior?
IntermediateA class decorator (a function taking a class and returning a class, possibly modified) runs once after the class is fully created, making it simpler for straightforward modifications like adding methods or registering the class. A metaclass intervenes during the class creation process itself (before the class object fully exists), giving it more power -- like controlling the namespace, validating during creation, or affecting all subclasses automatically -- at the cost of more complexity.
def add_repr(cls):
cls.__repr__ = lambda self: f'{cls.__name__}({self.__dict__})'
return cls
@add_repr
class Point:
def __init__(self, x, y):
self.x, self.y = x, y
print(Point(1,2)) # Point({'x': 1, 'y': 2})
Real-world example
A dataclass-like library offers both a simpler @auto_repr class decorator for basic use and a full metaclass-based system for advanced users needing automatic subclass registration.
Decorators;Dataclasses & NamedTuples
Why can't you freely mix two classes with different, incompatible metaclasses in multiple inheritance?
AdvancedWhen a class inherits from multiple bases with different metaclasses, Python must determine a single metaclass for the new class that is a subclass of all the bases' metaclasses (found via metaclass conflict resolution); if no such common metaclass exists, Python raises `TypeError: metaclass conflict`. This is why combining ABCMeta-based classes with other custom metaclasses sometimes requires defining a new metaclass that inherits from both.
class MetaA(type): pass
class MetaB(type): pass
class A(metaclass=MetaA): pass
class B(metaclass=MetaB): pass
try:
class C(A, B): pass # TypeError: metaclass conflict
except TypeError as e:
print(e)
Real-world example
Combining a third-party ORM base class (using a custom metaclass) with an ABC-based interface sometimes forces you to define `class CombinedMeta(ORMMeta, ABCMeta): pass` and use it explicitly to resolve the conflict.
Multiple Inheritance & MRO;Descriptors & Properties
How does __set_name__ let a descriptor discover the attribute name it's assigned to within a class?
Intermediate__set_name__(self, owner, name) is automatically called on a descriptor instance by the class creation machinery (part of type.__new__), passing the owning class and the attribute name it was assigned to in the class body. This lets descriptors avoid requiring the name to be passed explicitly and manually kept in sync, reducing a common source of bugs.
class Field:
def __set_name__(self, owner, name):
self.name = f'_{name}'
def __get__(self, obj, objtype=None):
return getattr(obj, self.name, None)
def __set__(self, obj, value):
setattr(obj, self.name, value)
class Model:
title = Field() # __set_name__ called automatically with name='title'
Real-world example
A validation library's Field descriptor uses __set_name__ to automatically derive its private storage attribute name from the public attribute name, eliminating a common copy-paste bug of mismatched names.
Descriptors & Properties;Data Types & Structures
Showing 1–10 of 15