Skip to content

Commit cd25eca

Browse files
Add python-metaclasses materials for the Python Metaclasses tutorial
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent d867710 commit cd25eca

15 files changed

Lines changed: 257 additions & 0 deletions

python-metaclasses/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Python Metaclasses
2+
3+
This folder provides the code examples for the Real Python tutorial [Python Metaclasses](https://realpython.com/python-metaclasses/).
4+
5+
The tutorial demonstrates its examples in the interactive interpreter, so each
6+
REPL sequence is collected here as a runnable script that prints the output the
7+
tutorial shows. Run any of them with Python 3.14:
8+
9+
```sh
10+
$ python custom_metaclass.py
11+
```
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
def decorator(cls):
2+
class NewClass(cls):
3+
attr = 100
4+
5+
return NewClass
6+
7+
8+
@decorator
9+
class X:
10+
pass
11+
12+
13+
@decorator
14+
class Y:
15+
pass
16+
17+
18+
@decorator
19+
class Z:
20+
pass
21+
22+
23+
print(X.attr)
24+
print(Y.attr)
25+
print(Z.attr)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class Meta(type):
2+
def __init__(cls, name, bases, dct):
3+
cls.attr = 100
4+
5+
6+
class X(metaclass=Meta):
7+
pass
8+
9+
10+
print(X.attr)
11+
12+
13+
class Y(metaclass=Meta):
14+
pass
15+
16+
17+
print(Y.attr)
18+
19+
20+
class Z(metaclass=Meta):
21+
pass
22+
23+
24+
print(Z.attr)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class Meta(type):
2+
def __new__(cls, name, bases, dct):
3+
x = super().__new__(cls, name, bases, dct)
4+
x.attr = 100
5+
return x
6+
7+
8+
class Foo(metaclass=Meta):
9+
pass
10+
11+
12+
print(Foo.attr)
13+
14+
15+
class Bar(metaclass=Meta):
16+
pass
17+
18+
19+
class Qux(metaclass=Meta):
20+
pass
21+
22+
23+
print((Bar.attr, Qux.attr))
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class Foo:
2+
pass
3+
4+
5+
def new(cls):
6+
x = object.__new__(cls)
7+
x.attr = 100
8+
return x
9+
10+
11+
Foo.__new__ = new
12+
13+
f = Foo()
14+
print(f.attr)
15+
16+
g = Foo()
17+
print(g.attr)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Defining the class dynamically with type()
2+
Foo = type("Foo", (), {})
3+
4+
x = Foo()
5+
print(x)
6+
7+
8+
# The same class defined the usual way, with the class statement
9+
class Foo:
10+
pass
11+
12+
13+
x = Foo()
14+
print(x)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Foo comes from Example 1
2+
Foo = type("Foo", (), {})
3+
4+
# Defining the class dynamically with type()
5+
Bar = type("Bar", (Foo,), dict(attr=100))
6+
7+
x = Bar()
8+
print(x.attr)
9+
print(x.__class__)
10+
print(x.__class__.__bases__)
11+
12+
13+
# The same class defined the usual way, with the class statement
14+
class Bar(Foo):
15+
attr = 100
16+
17+
18+
x = Bar()
19+
print(x.attr)
20+
print(x.__class__)
21+
print(x.__class__.__bases__)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Defining the class dynamically with type()
2+
Foo = type("Foo", (), {"attr": 100, "attr_val": lambda x: x.attr})
3+
4+
x = Foo()
5+
print(x.attr)
6+
print(x.attr_val())
7+
8+
9+
# The same class defined the usual way, with the class statement
10+
class Foo:
11+
attr = 100
12+
13+
def attr_val(self):
14+
return self.attr
15+
16+
17+
x = Foo()
18+
print(x.attr)
19+
print(x.attr_val())
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
def f(obj):
2+
print("attr =", obj.attr)
3+
4+
5+
# Defining the class dynamically with type()
6+
Foo = type("Foo", (), {"attr": 100, "attr_val": f})
7+
8+
x = Foo()
9+
print(x.attr)
10+
x.attr_val()
11+
12+
13+
# The same class defined the usual way, with the class statement
14+
class Foo:
15+
attr = 100
16+
attr_val = f
17+
18+
19+
x = Foo()
20+
print(x.attr)
21+
x.attr_val()
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class Foo:
2+
pass
3+
4+
5+
obj = Foo()
6+
print(obj.__class__)
7+
print(type(obj))
8+
print(obj.__class__ is type(obj))
9+
10+
n = 5
11+
d = {"x": 1, "y": 2}
12+
x = Foo()
13+
14+
for obj in (n, d, x):
15+
print(type(obj) is obj.__class__)

0 commit comments

Comments
 (0)