python - metaclass dalliance

In this post, we are going to examine two examples on the metaclasses - the first one is the use of 'type' function to create types (classes) dynamically, and another is the to subclass the 'type' type and use that new type as the metaclasses to create objects.
I actuallly will present two example together in one piece of code.


def init(self, x):
    self.x = x
def show(self):
    print(self.x)
# with the type class, you can create a type on the fly, where you can specify the
#   name
#   base classes
#   method list
# to that new type created
#  
Spam = type("Spam", (object,), {'__init__': init, 'show' : show})
def test_metaclass():
    class NewType(type):
        def __init__(cls, name, bases, dict):
            print("Create from newType")
            # super().__init__(cls, name, bases, dict)
            type.__init__(cls, name, bases, dict)
            cls.new_attr = "test"
    class Spam(metaclass = NewType):
        def __init__(self, x):
            self.x=x
        def show(self):
            print(self.x) # you will see the attribute from the parent 
    # you will see the meta-class be initialized 
    #  'Create from newType'
    # 
    print("", Spam.new_attr)
    print("type(Spam)", type(Spam)) # it will show NewType rather than type (normally if you don't override the metaclass, the result returned is 'type' 
    my_spam = Spam("Test")          # 
    print("type(my_spam)", type(my_spam)) # it will show __main__.Spam (just as any other variable will be  
    my_spam.show()
if __name__ == "__main__":
    my_spam = Spam("test")
    t = type(my_spam)
    print("*** ", t)
    t = type(Spam)
    print("*** ", t)
    my_spam.show()
    test_metaclass() # settle down on the test_metaclasses

as you can see, you can use the


Spam = type("Spam", (object,), {"__init__" : init, 'show' : show })

to create a type called “Spam”, as in the “Spam” string in the type function's parameter.

also, you can create a meta-class as subclass to the “type” type, then you can create types by explicitly assign “metaclass” attribute to the newly created “meta-class”.


class Spam(metaclass = NewType):
   pass

you may refer to my previous post in iteye on how to use the metaclass as a means to create simulation to “enum” in other languages such as java/C#.

Reference:

Use of Python metaclass II - Python Enumeration
Use of Python metaclass I - getattr for static/class variable

你可能感兴趣的:(python)