Skip to content

Commit 2c52d4f

Browse files
authored
Merge pull request #549 from realpython/python-protocol
Sample code for the article on Python protocols
2 parents cfdaba7 + df5edc3 commit 2c52d4f

22 files changed

+509
-0
lines changed

python-protocol/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Python Protocols: Leveraging Structural Subtyping
2+
3+
This folder provides the code examples for the Real Python tutorial [Python Protocols: Leveraging Structural Subtyping](https://realpython.com/python-protocol/).

python-protocol/adder_v1.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from typing import Protocol
2+
3+
4+
class Adder(Protocol):
5+
def add(self, x, y): ...
6+
7+
8+
class IntAdder:
9+
def add(self, x, y):
10+
return x + y
11+
12+
13+
class FloatAdder:
14+
def add(self, x, y):
15+
return x + y
16+
17+
18+
def add(adder: Adder) -> None:
19+
print(adder.add(2, 3))
20+
21+
22+
add(IntAdder())
23+
add(FloatAdder())
24+
25+
26+
for adder in [IntAdder(), FloatAdder()]:
27+
add(adder)

python-protocol/adder_v2.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from typing import Protocol
2+
3+
4+
class Adder(Protocol):
5+
def add(self, x: float, y: float) -> float: ...
6+
7+
8+
class IntAdder:
9+
def add(self, x: int, y: int) -> int:
10+
return x + y
11+
12+
13+
def add(adder: Adder) -> None:
14+
print(adder.add(2, 3))
15+
16+
17+
# add(IntAdder())

python-protocol/adder_v3.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from typing import Protocol
2+
3+
4+
class Adder(Protocol):
5+
def add(self, x: int | float, y: int | float) -> int | float: ...
6+
7+
8+
class IntAdder:
9+
def add(self, x: int, y: int) -> int:
10+
return x + y
11+
12+
13+
def add(adder: Adder) -> None:
14+
print(adder.add(2, 3))
15+
16+
17+
# add(IntAdder())

python-protocol/adder_v4.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from typing import Protocol, TypeVar
2+
3+
T = TypeVar("T", bound=int | float)
4+
5+
6+
class Adder(Protocol[T]):
7+
def add(self, x: T, y: T) -> T: ...
8+
9+
10+
class IntAdder:
11+
def add(self, x: int, y: int) -> int:
12+
return x + y
13+
14+
15+
class FloatAdder:
16+
def add(self, x: float, y: float) -> float:
17+
return x + y
18+
19+
20+
def add(adder: Adder) -> None:
21+
print(adder.add(2, 3))
22+
23+
24+
add(IntAdder())
25+
add(FloatAdder())

python-protocol/adder_v5.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from typing import Protocol
2+
3+
4+
class Adder(Protocol):
5+
def add[T: int | float | str](self, x: T, y: T) -> T: ...
6+
7+
8+
class IntAdder:
9+
def add(self, x: int, y: int) -> int:
10+
return x + y
11+
12+
13+
class FloatAdder:
14+
def add(self, x: float, y: float) -> float:
15+
return x + y
16+
17+
18+
def add(adder: Adder) -> None:
19+
print(adder.add(2, 3))
20+
21+
22+
add(IntAdder())
23+
add(FloatAdder())

python-protocol/adder_v6.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from typing import Protocol
2+
3+
4+
class Adder(Protocol):
5+
def add[T: int | float | str](self, x: T, y: T) -> T: ...
6+
7+
8+
class IntAdder:
9+
def add(self, x: int, y: int) -> int:
10+
return x + y
11+
12+
13+
class FloatAdder:
14+
def add(self, x: float, y: float) -> float:
15+
return x + y
16+
17+
18+
class StrAdder:
19+
def add(self, x: str, y: str) -> str:
20+
return x + y
21+
22+
23+
def add(adder: Adder) -> None:
24+
print(adder.add(2, 3))
25+
26+
27+
add(IntAdder())
28+
add(FloatAdder())
29+
add(StrAdder())

python-protocol/animals_v1.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class Animal:
2+
def __init__(self, name):
3+
self.name = name
4+
5+
def eat(self):
6+
print(f"{self.name} is eating.")
7+
8+
def drink(self):
9+
print(f"{self.name} is drinking.")
10+
11+
12+
class Dog(Animal):
13+
def bark(self):
14+
print(f"{self.name} is barking.")
15+
16+
17+
class Cat(Animal):
18+
def meow(self):
19+
print(f"{self.name} is meowing.")

python-protocol/animals_v2.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
class Dog:
2+
def __init__(self, name):
3+
self.name = name
4+
5+
def eat(self):
6+
print(f"{self.name} is eating.")
7+
8+
def drink(self):
9+
print(f"{self.name} is drinking.")
10+
11+
def make_sound(self):
12+
print(f"{self.name} is barking.")
13+
14+
15+
class Cat:
16+
def __init__(self, name):
17+
self.name = name
18+
19+
def eat(self):
20+
print(f"{self.name} is eating.")
21+
22+
def drink(self):
23+
print(f"{self.name} is drinking.")
24+
25+
def make_sound(self):
26+
print(f"{self.name} is meowing.")

python-protocol/birds_v1.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class Duck:
2+
def quack(self):
3+
return "The duck is quacking!"
4+
5+
6+
def make_it_quack(duck: Duck) -> str:
7+
return duck.quack()
8+
9+
10+
class Person:
11+
def quack(self):
12+
return "The person is imitating a duck quacking!"
13+
14+
15+
print(make_it_quack(Duck()))
16+
# print(make_it_quack(Person()))

0 commit comments

Comments
 (0)