Added example solutions to several chapters. Feel free to create a pull request with your answers. Also for the chapters that have no solutions yet :)

This commit is contained in:
Rick van Hattem
2022-09-05 00:04:00 +02:00
parent 82cf71ed1c
commit 500a31afac
34 changed files with 742 additions and 0 deletions
@@ -0,0 +1,16 @@
# Create a metaclass to test if attributes/methods are available.
class ExpectedAttrsMeta(type):
_expected_attrs = ['buy', 'sell']
def __new__(cls, name, bases, attrs):
for attr in cls._expected_attrs:
if attr not in attrs:
raise AttributeError(
f'{attr} attribute is missing from {name} class'
)
return super().__new__(cls, name, bases, attrs)
class Trade(metaclass=ExpectedAttrsMeta):
pass
@@ -0,0 +1,25 @@
# Create a metaclass to test if specific classes are inherited.
class SomeBaseClass:
pass
class ExpectedBasesMeta(type):
_expected_bases = [SomeBaseClass]
def __new__(cls, name, bases, attrs):
for base in cls._expected_bases:
if base not in bases:
raise TypeError(
f'{name} is not inheriting {base}'
)
return super().__new__(cls, name, bases, attrs)
class Trade(SomeBaseClass, metaclass=ExpectedBasesMeta):
pass
class BrokenTrade(metaclass=ExpectedBasesMeta):
pass
@@ -0,0 +1,29 @@
# Build a metaclass that wraps every method with a decorator (could be
# useful for logging/de- bugging purposes), something with a signature like
# this:
#
# class SomeClass(metaclass=WrappingMeta, wrapper=some_wrapper):
class WrappingMeta(type):
def __new__(cls, name, bases, attrs, wrapper):
for attr_name, attr_value in attrs.items():
if callable(attr_value):
attrs[attr_name] = wrapper(attr_value)
return super().__new__(cls, name, bases, attrs)
def print_call(func):
def wrapped(*args, **kwargs):
print(f'Calling {func.__name__}({args}, {kwargs})')
return func(*args, **kwargs)
return wrapped
class SomeClass(metaclass=WrappingMeta, wrapper=print_call):
def some_method(self):
print('some_method() called')
if __name__ == '__main__':
SomeClass().some_method()