关于装饰器:浅谈python装饰器的实现原理

一、装璜器在初学装璜器的时候,会感觉形象生涩,其实装璜器就是对某个对象进行性能上的加强上面具体讲一下 “加强” 的实现原理 二、加强的实现原理其实原理就一句话:更改旧对象的指向,指向 结构的新的函数wrapper def log(func): def wrapper(*args, **kw): print('call %s():' % func.__name__) return func(*args, **kw) return wrapper@logdef now(): print('2015-3-25')>>> now()call now():2015-3-25下面是拿廖雪峰-python-装璜器中的例子,在此做一个具体阐明:a. python解释器在执行now()之前,首先加载环境,加载内存中对应的程序 b. 找到后,自上而下执行,于是先执行 @log即执行: now = log(now) 咱们来具体看一下log(now)产生了什么,重点关注指向对象的变动1、首先解释器依据变量名log,找到内存中对应的程序2、now函数传入log函数,重点来了,参数func和now 此时指向同一个对象,即内存中存储的```def now(): print('2015-3-25')```3、此时解释器持续向下读取程序,直到遇到return返回。这里要留神,此时调用的是log函数,log外部的wrapper函数(闭包)此时并没有被调用,所以此时执行log函数的return语句`return wrapper`log函数将`wrapper`返回c. log(now)返回wrapper,而后赋值给now,重点来了,now变量指向的对象从 def now(): print('2015-3-25')变为 def wrapper(*args, **kw): print('call %s():' % func.__name__) return func(*args, **kw)d. abc完结后,解释器执行完@log,接下来读取到now()语句,开始执行: 1. 此时now曾经和wrapper指向同一个对象,这里多说一句,其实此时如果运行 ``` >>> now.__name__ 'wrapper' ```如果想要防止这种状况,能够应用@functools.wraps(func)2. 咱们继续执行,遇到`print('call %s():' % func.__name__)`,执行print内容3. 遇到`return func(*args, **kw)`,还记得吗,下面咱们提到func指向的对象是谁?4. 调用func5. 解释器找到func指向的程序, ``` def now(): print('2015-3-25') ```6. 执行 `print('2015-3-25')`e. 至此,now()执行完结,依据abcd的阐明,大家应该能够了解返回的后果了 ...

January 19, 2022 · 1 min · jiezi

关于装饰器:设计模式之装饰器模式

基本概念装璜器模式,顾名思义起的是装璜的作用,就是在一个类上减少性能。如果通过继承来减少性能,在不批改代码的状况下,如果减少性能多的话,会使类的数量爆炸式增长,为治理带来微小的麻烦。装璜器模式就比拟好地解决了这一点。 介绍以下为装璜器模式的通用类图:  Component,个别是接口或者抽象类,定义了最简略的办法,装璜器类和被装璜类都要实现该接口。ConcreteComponent,被装璜类,实现了Component。Decorator,装璜器类,通过该类为ConcreteComponent动静增加额定的办法,实现了Component接口,并且该对象中持有一个Component的成员变量。ConcreteDecoratorA,ConcreteDecoratorB,具体的装璜类,该类中的办法就是要为ConcreteComponent动静增加的办法。实现咱们以生产一件衣服为例,生产一件衣服自身是个很简略的过程,一块布料裁剪好了之后做出衣服的样子就能够了,然而这样的衣服是卖不出去的,因为毫无美感,咱们须要通过一些装璜来使衣服变得难看。然而时代在变动,人们的审美也在变动,装璜总是一直在变的,所以咱们就要有一个灵活机动的模式来批改装璜。 Clothes.java public interface Clothes {     public void makeClothes(); } MakeClothes.javapublic class MakeClothes implements Clothes {      @Override     public void makeClothes() {         System.out.println("制作一件衣服");     }  } 步骤 3 创立装璜器。OperationSubstract.javapublic class OperationSubstract implements Strategy{    @Override    public int doOperation(int num1, int num2) {       return num1 - num2;    } } 话不多说,先来个衣服的最后成品,就是毫无美感的那种,那么如果当初要减少装璜,能够用一个类继承MakeClothes,而后减少外面makeClothes()办法,然而如果过几天装璜就变了,那么又要改变代码,而且如果装璜过多,这个类就显得很庞杂,不好保护,这个时候装璜器模式就来大显神通了。 Decorator.javapublic class Decorator implements Clothes {      private Clothes clothes;     public Decorator(Clothes _clothes) {         this.clothes = _clothes;     }     @Override     public void makeClothes() {         clothes.makeClothes();     } } 这就是一个装璜器,它有一个构造函数,参数是一个衣服类,同时它重写了makeClothes()办法,以便它的子类对其进行批改。上面是两个子类,别离对衣服进行了绣花和镂空 Embroidery.javapublic class Embroidery extends Decorator {      public Embroidery(Clothes _clothes) {         super(_clothes);     }     public void embroidery() {         System.out.println("给衣服绣花");     }     @Override     public void makeClothes() {         super.makeClothes();         this.embroidery();     } } Hollow.javapublic class Hollow extends Decorator {      public Hollow(Clothes _clothes) {         super(_clothes);     }     public void hollow() {         System.out.println("要害地位镂空");     }     @Override     public void makeClothes() {         super.makeClothes();         this.hollow();     } } 这两个子类的结构器都传入一个衣服模型,而且两个子类别离有各自的办法——绣花和镂空,然而他们均重写了makeClothes()办法,在制作衣服的过程中退出了绣花和镂空的操作,这样一来,咱们只须要增删改这几个装璜器的子类,就能够实现各种不同的装璜,简洁明了,高深莫测。上面测试一下: DecoratorDemo.javapublic class DecoratorDemo {      public static void main(String[] args) {         Clothes clothes = new MakeClothes();         clothes = new Embroidery(clothes);         clothes = new Hollow(clothes);         clothes.makeClothes();         System.out.println("衣服做好了");     } } 执行程序,输入后果: 制作一件衣服 给衣服绣花 要害地位镂空 衣服做好了

September 18, 2020 · 1 min · jiezi