File: LP6E/Chapter40/decoall_meta.py
"Apply any decorator to all methods of a class, with a metaclass"
from types import FunctionType
from decorators import tracer, timer
def decorateAll(decorator):
class MetaDecorate(type):
def __new__(meta, classname, supers, classdict):
for attr, attrval in classdict.items():
if type(attrval) is FunctionType:
classdict[attr] = decorator(attrval)
return type.__new__(meta, classname, supers, classdict)
return MetaDecorate
class Person(metaclass=decorateAll(tracer)): # Use a metaclass
def __init__(self, name, pay): # Pass any function decorator
self.name = name
self.pay = pay
def giveRaise(self, percent):
self.pay *= (1.0 + percent)
def lastName(self):
return self.name.split()[-1]
def tester(aPerson):
sue = aPerson('Sue Jones', 100_000)
bob = aPerson('Bob Smith', 50_000)
print(f'{sue.name=}, {bob.name=}')
sue.giveRaise(.10)
print(f'{sue.pay=:,.2f}')
print('Last names:', sue.lastName(), bob.lastName())
if __name__ == '__main__': tester(Person)