Using descriptor to implement class-level attributes in Python

Source: Internet
Author: User
The previous article briefly introduced the concept and use of the descriptor (descriptor) in Python, with the intention of the classmate estimating that the skill has been get√. This article gives a case once again by using a descriptor scenario, making it easier for students who don't understand the situation to understand.

Let's talk about decorator.

These two words are indeed somewhat similar, and are inseparable in use. This also creates an understanding of the difficulties, said the adorner and the description of what is going on, why must use an @ symbol plus a descriptor.

Many articles also combine these two, I will feel very around after reading them. Actually learning a point of knowledge, and doing project development a function is the same. When the function is split, we try to split the task small enough to be assigned to the developer. This guarantees the independence, completeness, and ease of progress management of each task. At the time of task development, you cannot put your tasks into a function/interface to avoid high coupling between functions, resulting in later difficult maintenance.

Again back to learn a technical point, if you always try to master two or more technical points, the results may be busy for a long time, found or disoriented.

Rub, as if to pull away.

Said descriptor is descriptor, decorator is decorator, encountered do not understand the place, conquer, where do not know point. So first say decorator, the key point is you have to realize that this is a grammatical sugar. The so-called syntactic sugar is what allows you to write code in a simple way. This is essentially the adorner (Decorator):
Copy the Code code as follows:


def decorator (func):
def wrapper ():
print ' in decorator '
Func ()
Return wrapper

def func ():
print ' in Func '

# Decorate the Func
Func = Decorator (func) # The left Func is actually that wrapper, you execute it when it will, it will help you execute func ()
# is equivalent to when you define Func plus @
@decorator
def func ():
print ' in Func '

The point: Through descriptor to do a class-level property

The common property is this:
Copy the Code code as follows:


Class Foo (object):
_name = ' The5fire '

@property
def name (self):
Return Self._name

The use of this property is an instance-level application. Because only after foo = foo (), you can foo.name.

But what if I needed a class-level attribute, like a classmethod, I could invoke without instantiating the class. The corresponding requirement is this, which defines a base class Dbmanage:
Copy the Code code 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 to execute this statement
return result

This actually corresponds to the underlying model of a table in the database, and I want the other models to inherit it, and then reuse the TABLE_NAME method (currently the method).

All I need to do is define the user model:
Copy the Code code as follows:


Class User (Dbmanage):
Pass


Then define the Post model:
Copy CodeThe code is as follows:


Class Post (Dbmanage):
Pass

This way, if I need to check all the User data, only User.select_all () is required, and the same is true for Post Post.select_all (). But at this point found a little uncomfortable things. That's the code for Cls.table_name () in the base class, and table_name looks like a property, but it needs to be fetched in the way it is called. Wrong.

A classproperty was then customized:
Copy the Code code as follows:


Class Classproperty (object):
def __init__ (Self, func):
Self.func = Func

def __get__ (self, instance, Klass):
Return Self.func (Klass)

This requires this, and my code in Dbmanage can be changed to:
Copy the Code code 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 for descriptor.
There may be someone or have a little doubt: for Mao you are not in SQL Assignment direct sql = "SELECT * from%s"% Cls.__name__.lower (). This question, ask very good, reason on one word: lazy. Too lazy to knock so much code every time.
  • Related Article

    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.