file manage-inst-meta pyhas the same effect as the prior decoratormanage instances like the prior examplebut with metaclass def tracer(classnamesupersclassdict)aclass type(classnamesupersclassdictclass wrapperdef __init__(self*args**kargs)self wrapped aclass(*args**kargsdef __getattr__(selfattrname)print('trace:'attrnamereturn getattr(self wrappedattrnamereturn wrapper on class creation call make client class class person(metaclass=tracer)def __init__(selfnamehoursrate)self name name self hours hours self rate rate def pay(self)return self hours self rate make person with tracer wrapper remembers person bob person('bob' print(bob nameprint(bob pay()bob is really wrapper wrapper embeds person triggers __getattr__ on instance creation catches all but wrapped delegate to wrapped object in-method fetch not traced this worksbut it relies on two tricks firstit must use simple function instead of classbecause type subclasses must adhere to object creation protocols secondit must manually create the subject class by calling type manuallyit needs to return an instance wrapperbut metaclasses are also responsible for creating and returning the subject class reallywe're using the metaclass protocol to imitate decorators in this examplerather than vice versabecause both run at the conclusion of class statementin many roles they are just variations on theme this metaclass version produces the same output as the decorator when run livec:\codepy - manage-inst-meta py tracename bob tracepay you should study both versions of these examples for yourself to weigh their tradeoffs in generalthoughmetaclasses are probably best suited to class managementdue to their designclass decorators can manage either instances or classesthough they may not be the best option for more advanced metaclass roles that we don' have space to cover in this book see the web for more metaclass examplesbut keep in mind that some are more appropriate than others (and some of their authors may know less of python than you do!exampleadding methods to classes