Deep mining of Python class and meta-class II "experience"

Source: Internet
Author: User
The previous article addressed some of the issues related to namespaces that might be encountered during the generation of instance objects by invoking class objects, and this time we went up one level to see how the class object itself was produced.

We know that the type () method can look at the types of an object, or that the object is generated by that class:

Print (type ()) Print (Type (' Python ')) class A:pass print (Type (A))

As you can see from this code, class object A is generated by type () , which means that the type can also be used to produce a new object, and that it produces a class object, so it is the class of all class objects:

Print (type.__doc__) type (object_or_name, bases, Dict) type (object), the object ' s type type (name, bases, Dict)-> ; A new type

The syntax for class definition classes is actually converted to type (name, bases, Dict), where the name parameter is the name of the class,bases is the tuple that inherits the parent class, dict the properties and methods of the class:

Class A:  pass# actually equals B = Type (' A ', (), {}) print (a.__name__ = = b.__name__) True

Theoretically, this is the meaning of the meta-class, but from a practical point of view it is more convenient and reasonable to use class syntax, whereas the real meaning of the meta-class is to construct a new meta-class by inheriting the type class and doing certain operations to produce class objects with specific behavior. So it seems that its nature is not different from ordinary class objects, except that it inherits the type class.

When the instance is built, it is initialized by calling the __init__ method, which is actually preceded by a call to the __new__ method to create the instance, and then initialize it through __init__ , as if __new __ is responsible for declaring variables, while __init__ is responsible for initializing the declared variables. One rule here is that the return value of the __new__ (CLS) must be an instance of the CLS parameter, otherwise __init__ will not fire, for example, in an enum. In the definition of enum, since the enumeration type is a singleton pattern, there is no return to the example when defining __new__ , and it will not be initialized:

Class Enum:def __new__ (CLS, value): Print (CLS, value) return value def __init__ (self): print ("would not be called!") E = Enum (1) 
 
  
   
   1
 
  

Typically, you define __new__ to create an instance of the CLS by calling the __new__ method of the parent class, as well as when defining the meta-class by invoking the use of the type mentioned above (since the meta-class inherits from 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=me Taenum): # The method of defining a meta-class in Python 2.7 is to use the __metaclass__ variable # [PEP 3115] (https://www.python.org/dev/peps/pep-3115/) # to Python 3 .0 after the syntax is changed to class Cls (metaclass=meta) test = 0 Metaclass:Name:Enum parents: () Attributes: {' __qualname__ ': ' Enum ', ' __module__ ': ' __main__ ', ' Test ': 0} Now let's look at the Enum class, which is no longer type but its meta-class Metaenum:type (enum) __main__. Metaenum

In addition to the __new__ method, PEP 3115 also defines the __prepare__ property, which is used to set the initialized namespace (that is, the 3rd parameter of type) or enum. Enum, for example, we need to restrict the behavior of the class by restricting the property names in the enumeration type from being reused:

# define a new dictionary class, when assigning a new dict[k] = V

# check if 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__ (Me  Taclass, name, Base, Attrs): Return Super (). __new__ (Metaclass, name, Base, Attrs) class Enum (metaclass=metaenum): Pass  Class Color (Enum): try:red = 1 red = 2 except typeerror:# There is no use of as err: why? Print ("TypeError catched") TypeError catched

 everything in Python is an object, all objects are instances of a class, or instances of a meta class, and type is its own meta-class and an instance of itself.

  • 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.