Python design pattern 5 decorator

Time:2022-1-9

The second structural pattern worth learning is the decorator pattern, which allows programmers to dynamically add capabilities to objects in a transparent way (affecting other objects).

Decorators can be written in a python way (which means using language features), thanks to the built-in decorator features(https://docs.python.org/3/reference/compound_stmts.html#function)。

A python decorator is a callable (function, method, or class) that obtains a function object func_ In as input and returns another function object func_ out。 It is used to extend the behavior of a function, method, or class.

Real world examples

Decorator mode is often used to extend the functionality of objects. In daily life, examples of this expansion include: adding a silencer to a gun, using different camera lenses, and so on.

Python design pattern 5 decorator

Django frame has a large number of ornaments

  • Restrict access to views for some HTTP requests
  • control
  • Control compression by single view
  • Control caching based on specific HTTP request headers

The pyramid framework and Zope application server also use decorators to achieve various goals.

  • Register the function as an event subscriber
  • Protect a method with specific permissions
  • Implement adapter mode

application

The decorator model shines across fields:

  • data validation
  • cache
  • journal
  • monitor
  • debugging
  • Business rules
  • encryption

Another common example of using the decorator pattern is the graphical user interface (GUI) toolset. In the GUI toolset, we hope to add some features, such as border, shadow, color and scrolling, to components / controls.

example

All recursive functions can benefit from caching, so let’s try to return the function number of the sum of the first n numbers_ sum()。

def number_sum(n): 
    '''Returns the sum of the first n numbers''' 
    assert(n >= 0), 'n must be >= 0' 
    
    if n == 0:
        return 0
    else:
        return n + number_sum(n-1)  
 
if __name__ == '__main__': 
    from timeit import Timer 
    t = Timer('number_sum(30)', 'from __main__ import number_sum')
    print('Time: ', t.timeit())

Time taken to execute output: time: 34.952999532999456

In the following code, we use dict to cache the calculated sum. We also changed the number passed to_ Arguments to the sum() function. We want to calculate the sum of the first 300 numbers, not just the first 30.

sum_cache = {0:0}
  
def number_sum(n): 
    '''Returns the sum of the first n numbers''' 
    assert(n >= 0), 'n must be >= 0'
    
    if n in sum_cache:
        return sum_cache[n]
    res = n + number_sum(n-1)
    # Add the value to the cache
    sum_cache[n] = res
    return res
         
if __name__ == '__main__': 
    from timeit import Timer 
    t = Timer('number_sum(300)', 'from __main__ import number_sum')
    print('Time: ', t.timeit())

Execution output time: time: 1.2133596080002462. Fast, but the single code is complex and inconvenient to reuse. Use LRU instead_ The cache decorator will be clearer:

from functools import lru_cache

@lru_cache
def number_sum(n): 
    '''Returns the sum of the first n numbers''' 
    assert(n >= 0), 'n must be >= 0' 
    
    if n == 0:
        return 0
    else:
        return n + number_sum(n-1)  
 
if __name__ == '__main__': 
    from timeit import Timer 
    t = Timer('number_sum(30)', 'from __main__ import number_sum')
    print('Time: ', t.timeit())

Recommended Today

The whole tutorial of docker installation and use, installation / complete command / dockerfile image production / docker container arrangement and one click installation of nginx + redis + MySQL / visualizer portal (version 2022)

官网: https://docs.docker.com/ 官网: https://www.docker.com/ docker 镜像市场: https://hub.docker.com/ 一、docker 说明 1.1、docker 核心 1、Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源,Docker 是一个 CS 架构软件。 2、Docker 是一个虚拟化轻量级linux服务器,可以解决我们在开发环境中运行配置问题 3.、Docker的主要目标是‘build ,ship and run any app,anywhere’,一次封装,到处运行 4、容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。 1.2、docker 版本问题 .Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),我们用社区版就可以了。 1.3、docker 架构( 3大核心) · 1、Images 镜像 (等于软件) · 2、Registry […]