defmy_annotation(func): defwrapper(*args, **kwargs): print("Before function execution") result = func(*args, **kwargs) print("After function execution") return result return wrapper
# This is from Armin Ronacher from Flash simplified later by six 这里说了我是抄的。。 defwith_metaclass(meta, *bases): """Create a base class with a metaclass.""" # This requires a bit of explanation: the basic idea is to make a dummy # metaclass for one level of class instantiation that replaces itself with # the actual metaclass. classmetaclass(meta): def__new__(cls, name, this_bases, d): return meta(name, bases, d) returntype.__new__(metaclass, str('temporary_class'), (), {})
# Create the new class - this pulls predefined "params" cls = super(MetaParams, meta).__new__(meta, name, bases, dct)
# Pulls the param class out of it - default is the empty class params = getattr(cls, 'params', AutoInfoClass)
# Pulls the packages class out of it - default is the empty class packages = tuple(getattr(cls, packs, ())) fpackages = tuple(getattr(cls, fpacks, ()))
# get extra (to the right) base classes which have a param attribute morebasesparams = [x.params for x in bases[1:] ifhasattr(x, 'params')]
# Get extra packages, add them to the packages and put all in the class for y in [x.packages for x in bases[1:] ifhasattr(x, packs)]: packages += tuple(y)
for y in [x.frompackages for x in bases[1:] ifhasattr(x, fpacks)]: fpackages += tuple(y)
# Subclass and store the newly derived params class cls.params = params._derive(name, newparams, morebasesparams)
return cls
defdonew(cls, *args, **kwargs): clsmod = sys.modules[cls.__module__] # import specified packages for p in cls.packages: ifisinstance(p, (tuple, list)): p, palias = p else: palias = p
pmod = __import__(p)
plevels = p.split('.') if p == palias andlen(plevels) > 1: # 'os.path' not aliased setattr(clsmod, pmod.__name__, pmod) # set 'os' in module
else: # aliased and/or dots for plevel in plevels[1:]: # recurse down the mod pmod = getattr(pmod, plevel)
setattr(clsmod, palias, pmod)
# import from specified packages - the 2nd part is a string or iterable for p, frompackage in cls.frompackages: ifisinstance(frompackage, string_types): frompackage = (frompackage,) # make it a tuple
for fp in frompackage: ifisinstance(fp, (tuple, list)): fp, falias = fp else: fp, falias = fp, fp # assumed is string
# complain "not string" without fp (unicode vs bytes) pmod = __import__(p, fromlist=[str(fp)]) pattr = getattr(pmod, fp) setattr(clsmod, falias, pattr) for basecls in cls.__bases__: setattr(sys.modules[basecls.__module__], falias, pattr)
# Create params and set the values from the kwargs params = cls.params() for pname, pdef in cls.params._getitems(): setattr(params, pname, kwargs.pop(pname, pdef))
# Create the object and set the params in place _obj, args, kwargs = super(MetaParams, cls).donew(*args, **kwargs) _obj.params = params _obj.p = params # shorter alias
# Parameter values have now been set before __init__ return _obj, args, kwargs
MetaBroker
子类,自己的__init__中添加了translations
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classMetaBroker(MetaParams): def__init__(cls, name, bases, dct): ''' Class has already been created ... fill missing methods if needed be ''' # Initialize the class super(MetaBroker, cls).__init__(name, bases, dct) translations = { 'get_cash': 'getcash', 'get_value': 'getvalue', }
for attr, trans in translations.items(): ifnothasattr(cls, attr): setattr(cls, name, getattr(cls, trans))