Before you look at the Meta class, look at the relationship between objects and classes in Python. Objects and Objects
In Python, the definition of a class is common in two ways:
1, Python built-in classes, such as: str, int, etc.
2, custom classes: It is common to use class to define
Class is instantiated, and there are two ways to get the object:
1, Python automatically recognizes classes and instantiates them, for example: x=100
2, display the invocation class instantiation, for example: obj =myclass ()
If you know the object, how to view the corresponding class:
Common 3 methods:
x =
type (x)
#<class ' int ' >
x.__class__
#<class ' int ' >
isinstance (x, int)
# True
class is an object
In Python, everything is a class, and the class is the first level object. In other words, the preceding int is also an object, is an object, there is a corresponding class, look at the next int class:
Type (int)
#<class ' type ' >
int.__class__
#<class ' type ' >
isinstance (int, type)
#True
The class with the built-in class is type.
So what does customization look like:
Class MyClass:
def __init__ (self):
print ("------")
type (myClass)
<class ' type ' >
myclass.__class__
<class ' type ' >
isinstance (myClass, type)
#True
The result is still the same.
Python's built-in classes and custom classes are all type, and the type class is also an object and what its class is:
Type (type)
#<class ' type ' >
type.__class__
#<class ' type ' >
isinstance (Type, type)
#True
That is, the final class with more classes or objects is the type class. Dynamic Definition Class
According to the above rules, type is the first class class (The Meta Class), the common built-in classes and custom-defined classes are class two, and are objects of the first class.
In addition to the common methods above, the method of defining a class can also use the first Class class type to generate objects of the first class, as well as classes of the second class, the class that we need:
Type (object_or_name, bases, Dict)
type (object)-> The object ' s type
type (name, bases, Dict)-> a new type
Use the method one to view the class of an object as shown earlier.
Type (object)-> The object ' s type
Method Two is to define the class dynamically
Type (name, bases, Dict)-> a new type
Name: The names of the classes to be defined
Bases: Inherited parent class, tuple
Dict: Defining properties of an object
class MyClass (object):
def __init__ (self):
sef.one = "Obj_one"
self.two = "Obj_two"
The above class can be defined by using type:
New_class = Type ("MyClass", (object,), {"One": "Obj_one", "two": "Obj_two"})
New_class is a reference to the defined class MyClass.
Adding an instance function to a class
Def p (self, k): Return
K
#self (an argument like the normal definition of a class's function) can also be defined as another name, which refers to the object itself.
New_class.my_method = P
Of course, you can continue to add object properties to the class
New_class.new_item = 88
Meta class-metaclass
Classes such as type used to create other classes are called Metaclass.
Based on the above statements, you can describe the Meta class, class, and object:
MyClass = Metaclass ()
MyObject = MyClass ()
In the python3.x
Custom META class:
Class Meta (type):
Pass
class Complex (Metaclass=meta):
pass
type (Complex)
<class ' __main__. Meta ' >
In the above example, if the class Meta becomes a meta class, the class complex must inherit from the meta by Metaclass, while in python2.x the class attribute is added: metaclass = Meta Example 1, modifying the attribute.
Create an API that allows users to create a series of interfaces that contain file objects, each of which should have a unique ID and contain an object to open the file. A user can write a specific method to accomplish a specific task. There are a lot of good ways to do this without having to explore the Meta class, so a simple example will illustrate the process.
Prime Minister, create interface Meta class, inherit from type:
Class Interfacemeta (Type):
def __new__ (CLS, name, parents, DCT):
# Create a class_id if it ' s not specified
if ' class_id ' not in DCT:
dct[' class_id '] = Name.lower ()
# Open the specified file for writing
if ' file ' in DC T:
filename = dct[' file ']
dct[' file ' = open (filename, ' W ')
# We need to call type.__new__ to complete the Initialization return
super (Interfacemeta, CLS). __new__ (CLS, name, parents, DCT)
The above changes the input dictionary to add a class ID if the class ID does not exist, and replaces the class file name with a class that points to the file name.
Use the Meta class interface to construct, instantiate an excuse object.
Interface = Interfacemeta (' Interface ', (), Dict (file= ' tmp.txt '))
print (interface.class_id)
#interface
Print (interface.file)
#<_io. Textiowrapper name= ' tmp.txt ' mode= ' W ' encoding= ' UTF-8 ' >
type (Interface)
#<class ' __main__ '. Interfacemeta ' >
The structure of the above is expected, the CLASS_ID variable is created, and the file class variable is replaced by the open file object.
Using the Meta class directly to create an interface class is a bit cumbersome and difficult to read.
The following uses Metaclass to create:
Class Interface (Metaclass = interfacemeta):
file = ' tmp.txt '
interface.file
#<_io. Textiowrapper name= ' tmp.txt ' mode= ' W ' encoding= ' UTF-8 ' >
type (Interface)
#<class ' __main__ '. Interfacemeta ' >
By Metaclass, a class constructs the class itself by using Interfacemeta instead of type.
Class UserInterface (Interface):
file = ' foo.txt '
userinterface.file
#<_io. Textiowrapper name= ' foo.txt ' mode= ' W ' encoding= ' UTF-8 ' >
userinterface.class_id
' userinterface ' Type (userinterface)
#<class ' __main__. Interfacemeta ' >
As you can see, any class that inherits from interface is built using the same meta class. Example 2: Registering a subclass
An automatic registry subclass that inherits from a given base class. For example, you may have another basic database interface, and you want users to be able to define their own interfaces, and these interfaces can be automatically stored in the primary registry.
Possible methods of processing:
Class Dbinterfacemeta (type):
# We use __init__ rather than __new__ this because we want
# to modify attributes of The class *after* they have been
# created
def __init__ (CLS, name, bases, DCT):
If not hasattr (CLS, ' Registry ' ): # This is the
base class. Create a empty registry
Cls.registry = {}
else:
# This is a derived class. Add CLS to the registry
interface_id = Name.lower ()
cls.registry[interface_id] = CLS
Super ( Dbinterfacemeta, CLS). __INIT__ (name, bases, DCT)
Meta class Simple Add Class A registry dictionary if the dictionary does not exist, and if registry already exists, the new class will be added to registry.
Work Flow:
Class Dbinterface (Metaclass = Dbinterfacemeta):
pass
print (dbinterface.registry)
#{}
Now, create some subclasses and double-check that they are added to the registry.
Class Firstinterface (Dbinterface):
Pass
class Secondinterface (dbinterface):
Pass
class Secondinterfacemodified (secondinterface):
pass
print (dbinterface.registry)
#{' secondinterface ': <class ' __main__. Secondinterface ', ' firstinterface ': <class ' __main__. Firstinterface ', ' secondinterfacemodified ': <class ' __main__. Secondinterfacemodified ' "}
The result is the same as expected. This can connect functions from registry, and user-defined interface-derived objects can be counted without the user remembering the new type of manual registration.
Reference articles
All about the metaclasses in python!
https://pythontips.com/2013/09/20/all-about-the-metaclasses-in-python/
A Primer on Python metaclasses
https://jakevdp.github.io/blog/2012/12/01/a-primer-on-python-metaclasses/