If you want to implement delayed operations in python, you need to apply time, and then use the sleep method of time
For example, I want to write an operation that delays printing once per second
import time for i in range(0, 10): time.sleep(1) print(i)
Delayed loading in Python is used a lot. The main idea is to delay the instantiation of the class to be introduced and save some time and space required for initialization.
This idea is also widely used in Django, such as ORM's QuerySet, and request.user in authentication middleware, etc. These all use the idea of delayed loading.
This article analyzes the idea of lazy loading through examples.
The basic idea of implementing lazy loading is to create a class, and we pass it the class we need to instantiate. At this time, the class will become a lazy loading class. When applied, Although I instantiated this lazy-loaded class, the class we want to reference is not instantiated.
Like the following:
class User(object): def __init__(self): self.name = 'haibo' self.age = 23 def test(): return User() #初始化该延迟加载类 user = CommonLazyObject(lambda :test()) #此时我们要引用的类才执行 user.age = 28
I defined a User class above, which is the class we want to reference in the program, and CommonLazyObject is the lazy loading class we defined (more on this later). By lazily loading the class, we do not need to initialize it in advance. It will only be instantiated when we want to perform operations such as user.age below.
Okay, let’s take a look at the specific implementation process of the lazy loading class.
Thought: Our instantiation operation will ultimately boil down to operators such as __getattr__ and __setattr__. Therefore, as long as we define these operators, we can achieve these delays, that is, only execution Only during these operations can we actually instantiate the class we want to instantiate:
#建立一个空的对象 empty = object() #一个装饰器,对__getattr__进行装饰,使得其可以进行类的实例化 def proxy_getattr(func): def wrapper(self,*args): if self._wrapper is empty: self._init_object() return func(self._wrapper,*args) return wrapper class LazyObject(object): def __init__(self): self._wrapper = empty __getattr__ = proxy_getattr(getattr) #进行赋值操作的时候,看是实例化类,还是对类的实例进行赋值操作。因为下面我们要进行实例化类的操作。 def __setattr__(self, key, value): if key == '_wrapper': self.__dict__['_wrapper'] = value else: if self._wrapper is empty: self._init_object() setattr(self._wrapper,key,value) #在子类中,你应该重新定义它,你通过它,来实现你想要通过何种方式实例化你的类。 def _init_object(self): pass
First look at the __setattr__ above. When we perform the assignment operation of user.age=28, this will be called operator, if the class we want to introduce is not instantiated in the delayed class, it will be instantiated first, that is, calling self._init_object and assigning it to _wrapper. If the instantiation is completed, the __setattr__ method of the instance will be executed immediately.
Similarly, __getattr_ is also the same. If I want to print user.name, I must first check whether the referenced class has been instantiated. If not, instantiate it first, and then call __getattr__ of the instance. .
Okay, let’s look at a subclass that implements instantiation:
class CommonLazyObject(LazyObject): def __init__(self,func): self.__dict__['_wrapperfunc'] = func super(CommonLazyObject,self).__init__() def _init_object(self): self._wrapper = self._wrapperfunc()
The instantiation process of this subclass is very simple, just call it directly.
The above is the detailed content of How to implement delayed operation in python. For more information, please follow other related articles on the PHP Chinese website!