ℹ️ Skipped - page is already crawled
| Filter | Status | Condition | Details |
|---|---|---|---|
| HTTP status | PASS | download_http_code = 200 | HTTP 200 |
| Age cutoff | PASS | download_stamp > now() - 6 MONTH | 0.1 months ago |
| History drop | PASS | isNull(history_drop_reason) | No drop reason |
| Spam/ban | PASS | fh_dont_index != 1 AND ml_spam_score = 0 | ml_spam_score=0 |
| Canonical | PASS | meta_canonical IS NULL OR = '' OR = src_unparsed | Not set |
| Property | Value |
|---|---|
| URL | https://www.academis.eu/advanced_python/classes/metaclasses.html |
| Last Crawled | 2026-04-15 02:26:55 (1 day ago) |
| First Indexed | 2024-06-06 19:52:56 (1 year ago) |
| HTTP Status Code | 200 |
| Meta Title | Metaclasses - Advanced Python |
| Meta Description | null |
| Meta Canonical | null |
| Boilerpipe Text | Metaclasses change the objects creation mechanics in Python.
The when Python creates an object, it calls the
__new__()
method of
the metaclass. The default behavior of
__new__()
is that it creates
an instance and calls its
__init__()
. Now you could write a new
metaclass that instead of calling
__init__()
does something else.
Valid Use Cases for changing a metaclass are:
writing an ORM like
Django models
or
SQLAlchemy
hijacking internal Python logic (e.g. like
pytest
does)
emulating JavaScript-like objects (the Prototype pattern)
Throughout 20 years of Python programming, I have not come across a
single situation where writing a metaclass was necessary. But it helps
to understand Python on a deeper level.
Simple Example
¶
Execute the example in
metaclasses.py
and see what it does.
Complex Example
¶
Here is a complex example for illustrative purposes.
The code might drive you nuts, so consider yourself warned!
run the code
admire what is happening
try to understand what is happening
return to 1
Here is the code:
class
CrazyMonkeyPack
(
type
):
def
__new__
(
mcs
,
name
,
bases
,
dict
):
cls
=
type
.
__new__
(
mcs
,
name
,
bases
,
dict
)
def
wrapper
(
*
args
):
instance
=
[]
for
i
in
range
(
1
,
args
[
0
]
+
1
):
monkey
=
cls
(
f
'monkey #
{
i
}
'
)
# calls __init__
monkey
.
state
=
'crazy'
# monkey-patches the state attribute
instance
.
append
(
monkey
)
return
instance
return
wrapper
class
CrazyMonkeys
(
metaclass
=
CrazyMonkeyPack
):
"""A self-expanding horde of monkeys"""
def
__init__
(
self
,
name
):
self
.
name
=
name
def
__repr__
(
self
):
return
f
"<
{
self
.
name
}
(
{
self
.
state
}
)>"
monkeys
=
CrazyMonkeys
(
3
)
# calls __new__
print
(
monkeys
)
# see what happens!
Warning
Don’t try using metaclasses at work, unless
you have excluded all alternatives
you really know what you are doing
you have talked to an experienced developer |
| Markdown | [Skip to content](https://www.academis.eu/advanced_python/classes/metaclasses.html#furo-main-content)
[Advanced Python](https://www.academis.eu/advanced_python/index.html)
[ Advanced Python](https://www.academis.eu/advanced_python/index.html)
- [Revisit Python Basics](https://www.academis.eu/advanced_python/debugging/README.html)
- [Building a Python Package](https://www.academis.eu/advanced_python/python_package/README.html)
- [Set up a GitHub Repository](https://www.academis.eu/advanced_python/getting_started/git_repo.html)
- [Create a Folder Structure](https://www.academis.eu/advanced_python/getting_started/structure.html)
- [Writing a new Function](https://www.academis.eu/advanced_python/functions/levels.html)
- [Function parameters](https://www.academis.eu/advanced_python/functions/function_parameters.html)
- [Variable Scope](https://www.academis.eu/advanced_python/functions/scope.html)
- [Generators](https://www.academis.eu/advanced_python/functions/generators.html)
- [Map-Filter-Reduce](https://www.academis.eu/advanced_python/functions/functools.html)
- [Decorators](https://www.academis.eu/advanced_python/functions/decorators.html)
- [Collections](https://www.academis.eu/advanced_python/shortcuts/collections.html)
- [Comprehensions](https://www.academis.eu/advanced_python/shortcuts/comprehensions.html)
- [Enumerations](https://www.academis.eu/advanced_python/shortcuts/enums.html)
- [Demographics](https://www.academis.eu/advanced_python/challenges/demographics.html)
- [Refactoring](https://www.academis.eu/advanced_python/refactoring/README.html)
- [Structure of a Python script](https://www.academis.eu/advanced_python/structure/main_block.html)
- [Command-line Arguments](https://www.academis.eu/advanced_python/structure/commandline_args.html)
- [Modules](https://www.academis.eu/advanced_python/structure/modules.html)
- [Packages](https://www.academis.eu/advanced_python/structure/modules.html#packages)
- [Namespaces](https://www.academis.eu/advanced_python/structure/namespaces.html)
- [Classes](https://www.academis.eu/advanced_python/classes/classes.html)
- [Inheritance](https://www.academis.eu/advanced_python/classes/inheritance.html)
- [Object Composition](https://www.academis.eu/advanced_python/classes/composition.html)
- [Class Diagrams](https://www.academis.eu/advanced_python/classes/class_diagram.html)
- [Operator Overloading](https://www.academis.eu/advanced_python/classes/operator_overloading.html)
- [Properties, classmethods and staticmethods](https://www.academis.eu/advanced_python/classes/properties.html)
- [Abstract Base Classes](https://www.academis.eu/advanced_python/classes/abc.html)
- [Decorator Classes](https://www.academis.eu/advanced_python/classes/decorator_class.html)
- [Metaclasses](https://www.academis.eu/advanced_python/classes/metaclasses.html)
- [OOP Principles](https://www.academis.eu/advanced_python/classes/oop_principles.html)
- [Static Code Checks](https://www.academis.eu/advanced_python/quality/code_checks.html)
- [Test Automation](https://www.academis.eu/advanced_python/testing/README.html)
- [Continuous Integration](https://www.academis.eu/advanced_python/quality/continuous_integration.html)
- [Debugging](https://www.academis.eu/advanced_python/error_handling/debugging.html)
- [Interactive Python Debugger](https://www.academis.eu/advanced_python/error_handling/interactive_debugger.html)
- [Handling Exceptions](https://www.academis.eu/advanced_python/error_handling/exceptions.html)
- [Warnings](https://www.academis.eu/advanced_python/error_handling/warnings.html)
- [Logging](https://www.academis.eu/advanced_python/error_handling/logging.html)
- [Measuring Performance](https://www.academis.eu/advanced_python/performance/profiling.html)
- [Concurrency](https://www.academis.eu/advanced_python/concurrency/README.html)
- [The Dungeon Explorer Game](https://www.academis.eu/advanced_python/software_engineering/README.html)
- [The Prototype](https://www.academis.eu/advanced_python/software_engineering/prototype.html)
- [Code Reviews](https://www.academis.eu/advanced_python/software_engineering/code_review.html)
- [Factorials](https://www.academis.eu/advanced_python/challenges/factorial.html)
- [Sorting Algorithms](https://www.academis.eu/advanced_python/challenges/sorting.html)
- [Dice](https://www.academis.eu/advanced_python/challenges/dice/dice.html)
- [Tennis](https://www.academis.eu/advanced_python/challenges/tennis.html)
- [Memory](https://www.academis.eu/advanced_python/challenges/memory/memory.html)
- [Magic Square](https://www.academis.eu/advanced_python/challenges/magic_square.html)
- [Josephus’ Problem](https://www.academis.eu/advanced_python/challenges/josephus.html)
- [Binary Search](https://www.academis.eu/advanced_python/challenges/binary_search.html)
- [Tree Traversal](https://www.academis.eu/advanced_python/challenges/tree_traversal.html)
- [Graph Traversal](https://www.academis.eu/advanced_python/challenges/maze.html)
- [Backpack Problem](https://www.academis.eu/advanced_python/challenges/backpack_problem.html)
- [Chained List](https://www.academis.eu/advanced_python/challenges/chained_list.html)
- [Traveling Salesman](https://www.academis.eu/advanced_python/challenges/tsp.html)
- [Blockchain](https://www.academis.eu/advanced_python/challenges/blockchain.html)
- [Decorators with a Metaclass](https://www.academis.eu/advanced_python/challenges/metaclass.html)
- [Project: Implement a Game](https://www.academis.eu/advanced_python/project.html)
- [Hall of Fame](https://www.academis.eu/advanced_python/hall_of_fame.html)
- [Breakout](https://www.academis.eu/advanced_python/examples/breakout.html)
- [Tetris](https://www.academis.eu/advanced_python/examples/tetris.html)
- [Links](https://www.academis.eu/advanced_python/links.html)
[Back to top](https://www.academis.eu/advanced_python/classes/metaclasses.html)
[View this page](https://github.com/krother/advanced_python/blob/master/classes/metaclasses.rst?plain=true "View this page")
[Edit this page](https://github.com/krother/advanced_python/edit/master/classes/metaclasses.rst "Edit this page")
# Metaclasses[¶](https://www.academis.eu/advanced_python/classes/metaclasses.html#metaclasses "Link to this heading")
Metaclasses change the objects creation mechanics in Python.
The when Python creates an object, it calls the `__new__()` method of the metaclass. The default behavior of `__new__()` is that it creates an instance and calls its `__init__()`. Now you could write a new metaclass that instead of calling `__init__()` does something else.
Valid Use Cases for changing a metaclass are:
- writing an ORM like **Django models** or **SQLAlchemy**
- hijacking internal Python logic (e.g. like **pytest** does)
- emulating JavaScript-like objects (the Prototype pattern)
Throughout 20 years of Python programming, I have not come across a single situation where writing a metaclass was necessary. But it helps to understand Python on a deeper level.
## Simple Example[¶](https://www.academis.eu/advanced_python/classes/metaclasses.html#simple-example "Link to this heading")
Execute the example in [`metaclasses.py`](https://www.academis.eu/advanced_python/_downloads/1faa83337d8d0736014f2889a475e37b/metaclasses.py) and see what it does.
## Complex Example[¶](https://www.academis.eu/advanced_python/classes/metaclasses.html#complex-example "Link to this heading")
Here is a complex example for illustrative purposes. The code might drive you nuts, so consider yourself warned\!
1. run the code
2. admire what is happening
3. try to understand what is happening
4. return to 1
Here is the code:
```
class CrazyMonkeyPack(type):
def __new__(mcs, name, bases, dict):
cls = type.__new__(mcs, name, bases, dict)
def wrapper(*args):
instance = []
for i in range(1, args[0]+1):
monkey = cls(f'monkey #{i}') # calls __init__
monkey.state = 'crazy' # monkey-patches the state attribute
instance.append(monkey)
return instance
return wrapper
class CrazyMonkeys(metaclass=CrazyMonkeyPack):
"""A self-expanding horde of monkeys"""
def __init__(self, name):
self.name = name
def __repr__(self):
return f"<{self.name} ({self.state})>"
monkeys = CrazyMonkeys(3) # calls __new__
print(monkeys) # see what happens!
```
Warning
Don’t try using metaclasses at work, unless
- you have excluded all alternatives
- you really know what you are doing
- you have talked to an experienced developer
[Next OOP Principles](https://www.academis.eu/advanced_python/classes/oop_principles.html)
[Previous Decorator Classes](https://www.academis.eu/advanced_python/classes/decorator_class.html)
Copyright © 2024, Kristian Rother
Made with [Sphinx](https://www.sphinx-doc.org/) and [@pradyunsg](https://pradyunsg.me/)'s [Furo](https://github.com/pradyunsg/furo)
On this page
- [Metaclasses](https://www.academis.eu/advanced_python/classes/metaclasses.html)
- [Simple Example](https://www.academis.eu/advanced_python/classes/metaclasses.html#simple-example)
- [Complex Example](https://www.academis.eu/advanced_python/classes/metaclasses.html#complex-example) |
| Readable Markdown | Metaclasses change the objects creation mechanics in Python.
The when Python creates an object, it calls the `__new__()` method of the metaclass. The default behavior of `__new__()` is that it creates an instance and calls its `__init__()`. Now you could write a new metaclass that instead of calling `__init__()` does something else.
Valid Use Cases for changing a metaclass are:
- writing an ORM like **Django models** or **SQLAlchemy**
- hijacking internal Python logic (e.g. like **pytest** does)
- emulating JavaScript-like objects (the Prototype pattern)
Throughout 20 years of Python programming, I have not come across a single situation where writing a metaclass was necessary. But it helps to understand Python on a deeper level.
## Simple Example[¶](https://www.academis.eu/advanced_python/classes/metaclasses.html#simple-example "Link to this heading")
Execute the example in [`metaclasses.py`](https://www.academis.eu/advanced_python/_downloads/1faa83337d8d0736014f2889a475e37b/metaclasses.py) and see what it does.
## Complex Example[¶](https://www.academis.eu/advanced_python/classes/metaclasses.html#complex-example "Link to this heading")
Here is a complex example for illustrative purposes. The code might drive you nuts, so consider yourself warned\!
1. run the code
2. admire what is happening
3. try to understand what is happening
4. return to 1
Here is the code:
```
class CrazyMonkeyPack(type):
def __new__(mcs, name, bases, dict):
cls = type.__new__(mcs, name, bases, dict)
def wrapper(*args):
instance = []
for i in range(1, args[0]+1):
monkey = cls(f'monkey #{i}') # calls __init__
monkey.state = 'crazy' # monkey-patches the state attribute
instance.append(monkey)
return instance
return wrapper
class CrazyMonkeys(metaclass=CrazyMonkeyPack):
"""A self-expanding horde of monkeys"""
def __init__(self, name):
self.name = name
def __repr__(self):
return f"<{self.name} ({self.state})>"
monkeys = CrazyMonkeys(3) # calls __new__
print(monkeys) # see what happens!
```
Warning
Don’t try using metaclasses at work, unless
- you have excluded all alternatives
- you really know what you are doing
- you have talked to an experienced developer |
| Shard | 69 (laksa) |
| Root Hash | 1753711494307466869 |
| Unparsed URL | eu,academis!www,/advanced_python/classes/metaclasses.html s443 |