Detailed description of using Descriptor to implement class-level properties in Python

Source: Internet
Author: User
This article mainly introduces how to use Descriptor to implement class-level properties in Python. This article first explains what decorator is and then provides a class-level Property instance through Descriptor, you can refer to the previous article to briefly introduce the concept and use of the Descriptor in python. This article uses a Descriptor application scenario to give another case, so that those who do not know the situation can be more easily understood.

Decorator

These two words are indeed similar, and they are inseparable in use. This also makes it difficult for humans to understand. they say what is going on with the decorator and the describer, and why do they have to add the describer with a @ symbol.

Many articles also combine these two articles. after reading these articles, I will find them very difficult. Actually, learning a knowledge point is the same as developing a project. When splitting functions, we will try our best to split the tasks small enough to allocate them to developers. This ensures the independence and integrity of each task and is easy to manage the progress. During Task development, you cannot place all your tasks in a function or interface to avoid high coupling between functions, making it difficult to maintain tasks in the future.

Let's go back to learning a technical point. if you always try to master two or more technical points at once, the result may be that you have been busy for a long time and are confused.

It seems to be far away.

Descriptor is a Descriptor, and Decorator is a Decorator. if you encounter something you don't understand, you can break through it and find out where you don't know. So let's talk about Decorator first. The key point is that you need to realize that this is a syntactic sugar. The so-called syntactic sugar allows you to write code in a simple way. Essentially, Decorator is like this:

The code is as follows:


Def decorator (func ):
Def wrapper ():
Print 'in recorator'
Func ()
Return wrapper

Def func ():
Print 'in func'

# Decorate func
Func = decorator (func) # The func on the left is actually the wrapper. when you execute it, it will help you execute func ()
# Equivalent to adding @ When defining func @
@ Decorator
Def func ():
Print 'in func'

Question: use Descriptor to create a class-level Property

The common Property is as follows:

The code is as follows:


Class Foo (object ):
_ Name = 'the5fire'

@ Property
Def name (self ):
Return self. _ name

In this example, the use of property is an instance-level application. Because foo. name can be used only after Foo = foo.

However, if I need a class-level attribute, just like classmethod, I can call it without instantiating the class. The corresponding requirement is as follows. a base class DBManage is defined:

The code is as follows:


Class DBManage (object ):
@ Classmethod
Def table_name (cls ):
Return cls. _ name _. lower ()

@ Classmethod
Def select_all (cls ):
SQL = "SELECT * FROM % s" % cls. table_name ()
# Code for executing this statement
Return result

This actually corresponds to the basic Model of a table in the database. I want other models to inherit it, and then I can reuse the table_name method (currently it is still a method ).

I just need to define the User model as follows:

The code is as follows:


Class User (DBManage ):
Pass


Then define the Post model as follows:

The code is as follows:


Class Post (DBManage ):
Pass

In this way, if you need to query all User data, you only need User. select_all (). Similarly, Post. select_all () is also the case for Post. select_all (). But now I find it a bit uncomfortable. That is the code cls. table_name () in the base class. table_name seems to be an attribute, but needs to be obtained by calling the method. Incorrect.

Therefore, a classproperty is customized:

The code is as follows:


Class classproperty (object ):
Def _ init _ (self, func ):
Self. func = func

Def _ get _ (self, instance, klass ):
Return self. func (klass)

In this case, the code in DBManage can be changed:

The code is as follows:


Class DBManage (object ):
@ Classproperty
Def table_name (cls ):
Return cls. _ name _. lower ()

@ Classmethod
Def select_all (cls ):
SQL = "SELECT * FROM % s" % cls. table_name # How intuitive


This is another use case of Descriptor.
Someone may have a small question: when you assign a value to SQL, you can directly use SQL = "SELECT * FROM % s" % cls. _ name _. lower (). This is a very good question, for one reason: lazy. So much code is required every time.

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.