Python implements the class level Property of Property in Descriptor

  • 2020-04-02 14:09:33
  • OfStack

The previous article briefly introduced the concept and use of descriptors in python, and those of you who are interested in it probably got Square root . This article gives a case again through a Descriptor usage scenario, so that students who don't know the situation can understand it more easily.

First, the decorator

These two words are indeed somewhat similar, but they are also inseparable in use. This also makes it difficult to understand what is going on with decorators and descriptors, and why you need an @ sign with descriptors.

Many articles also combine these two words, I will feel very confusing after reading them. In fact, learning a knowledge point, and do a project to develop a function is the same. When it comes to splitting up functionality, we try to break down the tasks as small as possible and then assign them to the developer. This ensures that each task is independent, complete, and easy to manage. Nor can you put all your tasks into a single function/interface while developing tasks, to avoid a high coupling between functions that can be difficult to maintain later.

Going back to learning a skill, if you always try to master two or more skills at once, you may end up working for a long time and finding yourself still confused.

Eraser, I think I'm getting ahead of myself.

Descriptor is Descriptor, Decorator is Decorator, where you don't understand something, you break it down, where you don't understand something. So decorators, the point is to realize that this is a syntax sugar. Syntax sugar allows you to write code in a simple way. The Decorator is essentially this:


def decorator(func):
    def wrapper():
        print 'in decorator'
        func()
    return wrapper def func():
    print 'in func' # the func Decorate the
func = decorator(func)  # On the left side of the func It's actually that wrapper, When you do it, it does it for you func()
# You're defining func Time plus @
@decorator
def func():
    print 'in func'

Topic: do a class-level Property in Descriptor

A common Property looks like this:


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 () can foo.name be used.

But what if I need a class-level property, just like classmethod, I can call it without instantiating the class. The corresponding requirement is to define a base class DBManage:


class DBManage(object):
    @classmethod
    def table_name(cls):
        return cls.__name__.lower()     @classmethod
    def select_all(cls):
        sql = "SELECT * FROM %s""" % cls.table_name()
        # The code that executes this statement
        return result

This is actually a base Model for a table in the database, and I want all the other models to inherit it, and then I can reuse the table_name method (for now).

All I need to do is define the User model like this:


class User(DBManage):
    pass

Then define the Post model like this:

class Post(DBManage):
    pass

So if I need to look up all the User data, I just need user.select_all (), which is the same thing as Post. But then I found something a little uncomfortable. That's the code in the base class cls.table_name(). Table_name looks like an attribute, but you need to call a method to get it. Wrong.

So a custom classproperty is created:


class classproperty(object):
    def __init__(self, func):
        self.func = func     def __get__(self, instance, klass):
        return self.func(klass)

This requires that my code in DBManage be changed to:


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

So that's another use case for Descriptor.
S "s" % cls.s" % cls.s "s" % cls.s" s" s" s" s" s" s" s" s" s" s. This is a very good question, and the reason is one word: lazy. I'm too lazy to type that much code every time.


Related articles: