MetaClasses in Python

Source: Internet
Author: User
First, you need to know the class in python before you know metaclass. The strange features of class in python refer to the smalltalk language. In most languages, classes is only used to describe how to create an object's code end. To some extent, the same is true for the class in python. Those who have been familiar with Django should be familiar with its ORM system. For new python users, this is a feature that can almost be called "Black technology": as long as you define a Model subclass in models. py, Django can:

  1. Get its field definition and convert it into a table structure
  2. Read the internal Meta class and convert it into the corresponding configuration information. For special models (such as abstract and proxy), the corresponding conversion is also required.
  3. Add a default Manager for the Model without defining objects

In addition to development, I have made up the principles behind it. Once, I thought it was like this:

At startup, traverse all the attributes in models. py, locate the subclass of the Model, and make the above modifications to it.
At the beginning, I thought I had touched the truth and applied it to actual production. I wrote a class ORM System for KVDB of SAE. However, in the implementation process, I obviously felt the ugliness of this method, and the performance was not very good (because I had to traverse all the definition modules ).

So in fact, how does Django implement it?

Since ancient times, our methods for manufacturing things have been "top-down" and are made by means of cutting, splitting, and combination. However, life is built from the bottom up and spontaneously, and the process is extremely low. -- Wang Jinkang "seeding by Mercury"


This statement reveals the magic of life: real life is made up of the basic material, rather than the pipeline processing of the Creator.

If a class has its own life, its modification should not be completed by the caller, but should be spontaneous.

Fortunately, python provides the Creator's interface-this is Meta Classes, or "Meta class ".

What is a metabase?

To put it simply, the Meta class is the class of the class.

First, there must be a concept:

In python, everything is an object.

Yes, everything, including the class itself.

Since the class is an object and the object is an instance of the class, the -- class should also have a class.

Class: type

In python, we can use type to detect the class of an object, such:

print type(1) # 
 

What if I operate on a class?

print type(int) # 
 
  class MyClass(object): passprint type(MyClass) # 
  
   print type(type) # 
   
  
 

This indicates that type is actually a type. All classes, including the type itself, are type.

Type Introduction

From the official documentation, we can know:

Similar to dict, type is also a factory constructor. Calling it will return an instance of the type (class ).
Type has two overloaded versions:
+ 'Type (object) 'is the most common version.
+ 'Type (name, bases, dict) ', a more powerful version. A class is dynamically merged by specifying the class name ('name'), parent class list ('bases'), and attribute Dictionary ('dict.

The following two statements are equivalent:

Class Integer (int): name = 'my integer 'def increase (self, num): return num + 1 # ------------------- Integer = type ('integer', (int ,), {'name': 'My integer ', 'credentials': lambda self, num: \ num + 1 # Cool writing, isn't it })

That is to say, the class definition process is actually the process of type instantiation.

However, what does this have to do with modifying a defined class?

Of course ~ Since "Class Definition" is the initialization process of type ", the constructor of type (_ new _ () will be called __() or _ init __()). As long as we inherit the type class and modify its _ new _ function, we can start it here.

Next we will feel the dark magic of python through a chestnut, but before that, we should first understand a syntactic sugar.

_ Metaclass _ attributes

Do you think there are any ghost animals in the second example above? It allows programmers to write class members into a dictionary, which is simply against humanity. If we really want to change the behavior of the class by modifying the Meta class, it seems that we must adopt this method ~~ Terrible ~~

Fortunately, a syntax sugar __metaclass _ was introduced in python 2.2 __.

class Integer(int):  __metaclass__ = IntMeta

Now it will be equivalent:

Integer = IntMeta('Integer', (int, ), {})

As a result, we can also use the metadata class while using the traditional class definition.

Chestnut: subclass Purifier

Requirement Description

You are a language-friendly developer. You are not allowed to swear by others. This is also true during development. Now you have written a very good framework and will make it public soon. However, your obsessive-compulsive disorder: What if your user is full of foul words in the code? Isn't it a flaw in your purity?
What would you do if you were a mad developer?

You may not be able to get started before you know the metadata. However, you can easily solve this problem by using the Meta class-as long as the words that are not clean are filtered out during the class definition (Baidu Post Bar's work ~~).

Our Meta class looks like this:

Sensitive_words_list = ['asshole', 'fuck', 'shit'] def detect_sensitive_words (string): ''' sensitive vocabulary ''' words_detected = filter (lambda word: word in string. lower (), sensitive_words_list) if words_detected: raise NameError ('sensitive words {0} detected in the string "{1 }". '\. format (','. join (map (lambda s: '"% s"' % s, words_detected), string) class CleanerMeta (type): def _ new _ (cls, class_name, bas Es, attrs): detect_sensitive_words (class_name) # Check the class name map (detect_sensitive_words, attrs. iterkeys () # Check the attribute name print "Well done! You are a polite coder! "# If no exception occurs, the return super (CleanerMeta, cls). _ new _ (cls, class_name, bases, attrs) message is output. # important! This line must not be missed !! This call calls the built-in class constructor to construct the class. Otherwise, the defined class will become None. Now, you only need to define the base class: class APIBase (object) as follows ): _ metaclass _ = CleanerMeta #... then all APIBase Derived classes will undergo security review (smile ~~): Class ImAGoodBoy (APIBase): a_polite_attribute = 1 # [Output] Well done! You are a polite coder! Class FuckMyBoss (APIBase): pass # [Output] NameError: Sensitive words "fuck" detected in the string "FuckMyBoss ". class PretendToBePolite (APIBase): def _ fuck_your_asshole (self): pass # [Output] NameError: Sensitive words "asshole ", "fuck" detected in the string "_ PretendToBePolite _ fuck_your_asshole ".

Look, even the private attributes in the last example cannot be escaped because they are essentially the same.

You can even secretly modify problematic attributes, such as sending a line of warning when calling uncivilized functions.

Application of metadata in actual development

Is metadata frequently used during daily development?

Of course, Django's ORM is an example. The famous SQLAlchemy also uses this black magic.

In addition, there are also metadata in some small libraries. For example, abc (Strange name ~~) -- This is an internal library of python, used to simulate Abstract Base Classes ). Developers can use abc. the abstractmethod modifier specifies _ metaclass _ = abc. ABCMeta's class methods are defined as abstract methods. At the same time, this class has become an abstract base class. abstract base classes cannot be instantiated. This simulates the abstract base class.

If you need to dynamically modify the class definition, try this "Black Magic ".

Summary

  1. Classes are also objects, and all classes are type instances.
  2. Meta Classes is a class.
  3. _ Metaclass _ = Meta is the syntactic sugar of Meta (name, bases, dict ).
  4. You can modify the behavior of the class definition by reloading the _ new _ method of the metaclass.

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.