Last active
November 2, 2021 10:47
-
-
Save ryanhinkel/a4cb550b25d0a06e37572d909805fb8d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
In the following example, we can pretend that A and B are both classes that are provided by another framework or library | |
""" | |
class A: | |
cheetahs = "are fast" | |
def __getattr__(self, attr): | |
print("A is the getter") | |
if attr == "donuts": | |
return "are delicious" | |
class B: | |
elephants = "are large" | |
def __getattr__(self, attr): | |
print("B is the getter") | |
# B.__getattr__ will not be called because A does not delegate to it | |
if attr == "frenchtoast": | |
return "is filling" | |
class C(A, B): | |
def __init__(self): | |
self.data = { | |
"apples": "grow on trees", | |
"bees": "make honey", | |
} | |
def __getattr__(self, attr): | |
print("C is the getter") | |
if attr in self.data.keys(): | |
return self.data[attr] | |
# A.__getattr__ will be called only if we check for it and call it explicitly | |
elif hasattr(super(), '__getattr__'): | |
return getattr(super(), attr) | |
else: | |
raise AttributeError | |
c = C() | |
print(c.apples) # will be satisfied by C.__getattr__ | |
print(c.bees) # will be satisfied by C.__getattr__ | |
print(c.cheetahs) # will be satisfied by A.cheetah | |
print(c.donuts) # will be satisfied by A.__getattr__ | |
print(c.elephants) # will be satisfied by B.elephants | |
print(c.frenchtoast) # will dispatch first to C.__getattr__, then to A.__getattr__, | |
# and will return None because A does not call getattr on super, | |
# nor does it raise an attribute error. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment