-
Notifications
You must be signed in to change notification settings - Fork 0
/
abc_aside.py
76 lines (56 loc) · 2 KB
/
abc_aside.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# abc_aside.py
# !/usr/bin/env python3
from abc import ABC, abstractmethod
class Menu(ABC):
@abstractmethod
def add_spam(self) -> None:
raise NotImplementedError
@abstractmethod
def chef_special(self) -> None:
raise NotImplementedError
@classmethod
def __subclasshook__(cls, sub):
"""Required to support duck typing."""
return (
hasattr(sub, "add_spam")
and callable(sub.add_spam)
and hasattr(sub, "chef_special")
and callable(sub.chef_special)
) or NotImplemented # Not True or False
class LunchMenu(Menu):
def add_spam(self) -> None:
pass
def chef_special(self) -> None:
pass
# Possible because of inheritance of Menu class
assert LunchMenu.__mro__ == (LunchMenu, Menu, ABC, object) # True
assert isinstance(LunchMenu(), Menu) # True
assert issubclass(LunchMenu, Menu) # True
class TakeoutMenu:
def add_spam(self) -> None:
pass
def chef_special(self) -> None:
pass
# Possible because of __subclasshook__()
assert TakeoutMenu.__mro__ == (TakeoutMenu, object) # True, no menu or ABC
assert isinstance(TakeoutMenu(), Menu) # True
assert issubclass(TakeoutMenu, Menu) # True
@Menu.register
class DinnerMenu:
def add_spam(self) -> None:
pass
# Possible because of 'Or NotImplemented' condition in __subclasshook__()
assert DinnerMenu.__mro__ == (DinnerMenu, object) # True, no menu or ABC
assert isinstance(DinnerMenu(), Menu) # True, no chef_special
assert issubclass(DinnerMenu, Menu) # True, no chef_special
# Inheritance strictness in Python - from strict to less strict
# Class-based inheritance
# ABC
# ABC w/ __subclasshook__()
# ABC w/ register + __subclasshook__()
# Duck typing
# Sources:
# https://jarombek.com/blog/dec-15-2018-python-protocols-abcs
# https://jellis18.github.io/post/2022-01-11-abc-vs-protocol/
# http://leanpub.com/python-master (Robert Smallshire, Austin Bingham and Sixty North) # noqa
# https://peps.python.org/pep-3119/