Deep mining of Python and metabases II

Source: Internet
Author: User
Deep mining of Python classes and meta classes II let's go back to the next layer to see how class objects are generated.

We know that the type () method can view the type of an object, or determine which class the object is generated:

print(type(12))print(type('python'))
 
  
 
class A:    passprint(type(A))
 

Through this code, we can see that class object A is generated by type (), that is, type can also be used to generate new objects and produce class objects, therefore, it is the class of all class objects:

print(type.__doc__)
type(object_or_name, bases, dict)type(object) -> the object's typetype(name, bases, dict) -> a new type

The class definition class syntax is actually converted to type (name, bases, dict). The name parameter is the class name, and bases is the tuples that inherit the parent class, dict is a class property and method:

Class A: pass # is actually equal to B = type ('A', (), {}) print (A. _ name _ = B. _ name __)
True

In theory, this is the significance of the meta-class, but from the actual point of view, it is obvious that it is more convenient and reasonable to use the class syntax, the actual significance of the meta-class is to construct a new meta-class by inheriting the type class and perform specific operations to generate class objects with specific behaviors. In this way, it seems that its nature is no different from ordinary class objects, but it inherits the type class.

When an instance is generated, it is initialized by calling the _ init _ method. In fact, before that, the _ new _ method will be called to create an instance, then through _ init _ initialization, it is like _ new _ is responsible for declaring variables, while _ init _ is responsible for initializing declared variables. Here, there is a rule that the return value of _ new _ (cls,) must be an instance of the cls parameter, otherwise _ init _ will not be triggered, for example, in enum. in the definition of Enum, the instance is not returned when _ new _ is defined because the enumeration type is Singleton mode. Therefore, initialization is not performed:

class Enum:    def __new__(cls, value):        print(cls, value)        return value    def __init__(self):        print("Will not be called!")e = Enum(1)
 
   1
 

Generally, you need to call the _ new _ method of the parent class to create a cls instance, the usage of the type mentioned above is also called when the meta class is defined (because the meta class inherits from the type ):

class MetaEnum(type):    def __new__(metaclass, name, base, attrs):        print("Metaclass: {}\nName: {}\nParents: {}\nAttributes: {}".format(metaclass, name, base, attrs))        return super().__new__(metaclass, name, base, attrs)
Class Enum (metaclass = MetaEnum): # The way to define the metaclass in Python 2.7 is to use the _ metaclass _ variable # [PEP 3115] (https://www.python.org/dev/peps/pep-3115) # Change the syntax of Python 3.0 and later to class Cls (metaclass = Meta) test = 0
Metaclass: 
 
  Name: EnumParents: ()Attributes: {'__qualname__': 'Enum', '__module__': '__main__', 'test': 0}
 

Now let's look at the Enum class, which is no longer the type but its MetaEnum metadata:

Type (Enum)
_ Main _. MetaEnum

In addition to the _ new _ method, PEP 3115 also defines the _ prepare _ attribute, which is used to set the initialized namespace (that is, the 3rd parameters of type) or enum. for example, if you want to restrict the repeated use of attribute names in the enumeration type, you can use the behavior of the meta-class restriction class.

# Define a new dictionary class. when assigning a new dict [k] = v, # check whether k repeats class _ EnumDict (dict): def _ init _ (self ): super (). _ init _ () self. members = [] def _ setitem _ (self, k, v): if k in self. members: raise TypeError ("Attempted to reuse key :'{}'". format (k) else: self. members. append (k) super (). _ setitem _ (k, v) class MetaEnum (type): @ classmethod def _ prepare _ (metaclass, cls, bases): return _ EnumDict () def _ new _ (metaclass, n Ame, base, attrs): return super (). _ new _ (metaclass, name, base, attrs) class Enum (metaclass = MetaEnum): passclass Color (Enum): try: red = 1 red = 2 bytes T TypeError: # Why is as err not used here? Print ("TypeError catched ")
TypeError catched

In Python, everything is an object. all objects are instances of a certain type, or an instance of a certain mona1 class. type is its own metadata and its own instance:

Summary

Meta classes are a deep black magic in Python, which may not be commonly used in common applications, however, understanding the principles behind it is helpful for understanding Python object-oriented programming and the idea that everything is an object. if you need to perform in-depth class transformation, you must at least know where to start.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.