def __new__(meta, name, bases, dict): # @ Metaclass' __new__ serves as a bi-functional slot capable for # initiating the classes as well as alternating the meta. # @ Suggestion is putting majority of the class initialization code # in __init__, as you can directly reference to cls there; saving # here for anything you want to dynamically added to the meta (such # as shared variables or lazily GC'd temps). # @ Any changes here to dict will be visible to the new class and their # future instances, but won't affect the metaclass. While changes # directly through meta will be visible to all (unless you override # it later). dict['new_elem'] = "effective" meta.var = "Change made to %s by metaclass' __new__" % str(meta) meta.count += 1 print "================================================================" print " Metaclass's __new__ (creates class objects)" print "----------------------------------------------------------------" print "Bounded to object: " + str(meta) print "Bounded object's __dict__: " pprint(DictType(meta.__dict__), depth = 1) print "----------------------------------------------------------------" print "Parameter 'name': " + str(name) print "Parameter 'bases': " + str(bases) print "Parameter 'dict': " pprint(dict, depth = 1) print "\n" return super(FactoryMeta, meta).__new__(meta, name, bases, dict)
def __new__(cls, function): # @ Class' __new__ "creates" the instances. # @ This won't affect the metaclass. But it does alter the class' member # as it is bounded to cls. cls.extra = function print "================================================================" print " Class' __new__ (\"creates\" instance objects)" print "----------------------------------------------------------------" print "Bounded to object: " + str(cls) print "Bounded object's __dict__: " pprint(DictType(cls.__dict__), depth = 1) print "----------------------------------------------------------------" print "Parameter 'function': \n" + str(function) print "\n" return super(Factory, cls).__new__(cls)
def __init__(self, function, *args, **kwargs): # @ Class' __init__ initializes the instances. # @ Changes through self here (normally) won't affect the class or the # metaclass; they are only visible locally to the instances. # @ However, here you have another chance to make "static" things # visible to the instances, "locally". self.classFactory = self.__class__.classFactory print "================================================================" print " Class' __init__ (initiates instance objects)" print "----------------------------------------------------------------" print "Bounded to object: " + str(self) print "Bounded object's __dict__: " pprint(DictType(self.__dict__), depth = 1) print "----------------------------------------------------------------" print "Parameter 'function': \n" + str(function) print "\n" return super(Factory, self).__init__(*args, **kwargs)
def __init__(cls, name, bases, dict): # @ Metaclass' __init__ is the standard slot for class initialization. # Classes' common variables should mainly goes in here. # @ Any changes here to dict won't actually affect anything. While # changes directly through cls will be visible to the created class # and its future instances. Metaclass remains untouched. dict['init_elem'] = "defective" cls.var = "Change made to %s by metaclass' __init__" % str(cls) print "================================================================" print " Metaclass's __init__ (initiates class objects)" print "----------------------------------------------------------------" print "Bounded to object: " + str(cls) print "Bounded object's __dict__: " pprint(DictType(cls.__dict__), depth = 1) print "----------------------------------------------------------------" print "Parameter 'name': " + str(name) print "Parameter 'bases': " + str(bases) print "Parameter 'dict': " pprint(dict, depth = 1) print "\n" return super(FactoryMeta, cls).__init__(name, bases, dict)
def __call__(cls, *args): # @ Metaclass' __call__ gets called when a class name is used as a # callable function to create an instance. It is called before the # class' __new__. # @ Instance's initialization code can be put in here, although it # is bounded to "cls" rather than instance's "self". This provides # a slot similar to the class' __new__, where cls' members can be # altered and get copied to the instances. # @ Any changes here through cls will be visible to the class and its # instances. Metaclass remains unchanged. cls.var = "Change made to %s by metaclass' __call__" % str(cls) # @ "Static" methods defined in the meta which cannot be seen through # instances by default can be manually assigned with an access point # here. This is a way to create shared methods between different # instances of the same metaclass. cls.metaVar = FactoryMeta.metaVar print "================================================================" print " Metaclass's __call__ (initiates instance objects)" print "----------------------------------------------------------------" print "Bounded to object: " + str(cls) print "Bounded object's __dict__: " pprint(DictType(cls.__dict__), depth = 1) print "\n" return super(FactoryMeta, cls).__call__(*args)