装饰模式

python 简单元编程

夙愿已清 提交于 2020-02-26 02:27:57
软件开发领域中最经典的口头禅就是“don’t repeat yourself”。 也就是说,任何时候当你的程序中存在高度重复(或者是通过剪切复制)的代码时,都应该想想是否有更好的解决方案。 在Python当中,通常都可以通过元编程来解决这类问题。 简而言之,元编程就是关于创建操作源代码(比如修改、生成或包装原来的代码)的函数和类。 主要技术是使用装饰器、类装饰器和元类。   一、你想在函数上添加一个包装器,增加额外的操作处理(比如日志、计时等)。   之前思路:利用装饰器。   装饰器最基本的原理如下:   @timethis def countdown(n): pass   效果等同如下: def countdown(n): pass countdown = timethis(countdown)   所以我们在inner函数中实现我们想要的业务逻辑即可。 def wraper(func): def inner(*args,**kwargs): # 你想实现的额外功能 res = func() return res return inner 但是如果我们打印 func.__name__,就会出现inner,这个函数的重要的元信息比如名字、文档字符串、注解和参数签名都丢失了。   二、如何解决上述问题呢   注意:任何时候你定义装饰器的时候,都应该使用 functools 库中的

python装饰器

老子叫甜甜 提交于 2020-02-24 16:05:58
原则: 依赖倒置: 开放封闭:对扩展是开发的、对修改是封闭的 装饰器作用: 不想修改函数的调用方式,但是想在原来的函数前后添加功能 装饰器固定模式: import time def func(): time.sleep(0.01) print('hello') def timmer(f): # f也是一个变量 是一个闭包 # f=>func def inner(): start = time.time() f() print(time.time()-start) return inner func = timmer(func) # fun = inner func() # 执行 inner,内存没有消失f = func() 还有带返回值的、带参数的。 语法糖: import time def timmer(f): def inner(): start = time.time() f() print(time.time()-start) return inner @timmer def func(): time.sleep(0.01) print('hello') # func = timmer(func) func() 有语法糖 @timmer()就可以把func = timmer(func)去掉 背: 首先定义一函数 中间再加一函数 然后要加返回值 修饰函数中间套 语法糖呀真好吃

函数装饰器

家住魔仙堡 提交于 2020-02-24 16:04:37
装饰器 一、装饰器的形成过程 最简单的装饰器------->有返回值--------->有一个参数---------->万能参数 最简单的装饰器 import time def func(): time.sleep(1) print("大家好") def timmer(f): #装饰器函数 def inner(): start=time.time() f() #被装饰的函数 end=time.time() print(end-start) return inner func=timmer(func) #相当于inner() func 有返回值 import time def timmer(f): #装饰器函数 def inner(): start = time.time() ret = f() #被装饰的函数 end = time.time() print(end - start) return ret return inner @timmer #语法糖 @装饰器函数名 def func(): #被装饰的函数 time.sleep(0.01) print('老板好同事好大家好') return '新年好' # func = timmer(func) ret = func() #inner() print(ret) 装饰带参数函数的装饰器 import time def timmer

day 11 - 1 装饰器

旧城冷巷雨未停 提交于 2020-02-24 16:04:19
装饰器 装饰器形成的过程:最简单的装饰器——有返回值的——有一个参数——万能参数 装饰器的作用:不想修改函数的调用方式 但是还想在原来的函数前后添加功能 原则:开放封闭原则 语法糖:@装饰器函数名 装饰器的固定模式 原则:开放封闭原则 开放:对扩展是开放的 封闭:对修改是封闭的 首先我们来逐步实现这么一个功能吧 计算代码运行的时间 #先来看下需要的组件 import time #time 模块 time.time()   #获取当前时间 time.sleep(5)   #让程序睡眠多少时间 print(time.time()) #来试下 我们来写一个可以计算时间的函数 def func(): start=time.time() time.sleep(0.1) #时间太短 系统会显示 0.0,所以我们让他休眠 0.1s print("计算程序执行的时间") end=time.time() print(end-start) func() 但是这里有一个问题:如果要计算很多函数的运行时间,那不是要在函数中都加上几行计算的代码,这显然是不可行的,一般写好的没问题的函数,是不会去对它进行修改,而且还很麻烦 所以这里我们写一个计算时间的函数独立出来 def times(f): start=time.time() time.sleep(0.1) f() end=time.time() print

面向对象之魔术方法

懵懂的女人 提交于 2020-02-24 05:50:46
一、什么是魔术方法 在Python中,像__init__这类双下划线开头,双下划线结尾的方法,统称为魔术方法,魔术方法会在特定的时候自动调用; 注意: 魔术方法都是Python内部定义的,我们创建类的时候,不要定义双下划线开头和双下划线结尾这样的方法; 二、魔术方法 1、__new__方法 class MyClass(object): def __init__(self,name): self.name = name def __new__(cls, *args, **kwargs): print("这是自定义的new方法") # return super().__new__(cls) return object.__new__(cls) mc = MyClass("YEWEIYIN") 执行结果为: 这是自定义的new方法 __new__方法是创建对象时调用的第一个魔术方法,__new__方法在类的父类object类里面,它被@staticmethod装饰器装饰成了静态方法, 如果自己定义的类里面要重写__new__方法,则新定义的__new__方法一定要有retrun返回值,不然不能创建实例对象; 为了创建的实例对象能够调用类里面的方法,__new__方法返回的值要为类对象创建的实例对象,如果返回的是其他对象,则不能调用__init__方法初始化, __new_

从JavaScript中看设计模式(总结)

半城伤御伤魂 提交于 2020-02-18 14:27:52
本文原创文章,转载前请留言备注 概念 设计模式 (Design Pattern) 是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。 任何事情都有套路, 设计模式 就是写代码中常见的套路,有些写法我们日常都在使用,下面我们来介绍一下。 订阅/发布模式(观察者) pub/sub 这个应该大家用到的最广的设计 模式了 在这种模式中,并不是一个对象调用另一个对象的方法,而是一个对象 订阅 另一个对象 特定活动并在状态改变后获得通知,订阅者因此也成为观察者,而被观察的对象成为发布者或主题。当发生了一个重要事件的时候 发布者 会通知(调用)所有订阅者并且可能经常以事件对象的形式传递消息。 自己实现一个简单的发布订阅设计模式 // 创建EventBus class EventBus { constructor ( ) { // 储存事件 this . tasks = { } ; } // 绑定事件 $on ( eName , cb ) { typeof cb == "function" ? this . tasks [ eName ] || ( this . tasks [ eName ] = [ ] ) : this . Error ( cb , "is not a function" ) ; this . tasks [ eName ] . some ( fn => fn =

设计模式之装饰者模式

半世苍凉 提交于 2020-02-18 08:16:25
什么是装饰者模式? 装饰者模式以对客户透明的方式动态地给一个对象附加上更多的责任,装饰者模式相比生成子类可以更灵活地增加功能。 Component:一般是一个抽象类(也有可能不是),是一组有着某种用途类的基类,包含着这些类最基本的特性。 ConcreteComponent:继承自Component,一般是一个有实际用途的类,这个类就是我们以后要装饰的对象。 Decorator:继承自Component,装饰者需要共同实现的接口(也可以是抽象类),用来保证装饰者和被装饰者有共同的超类,并保证每一个装饰者都有一些必须具有的性质,如每一个装饰者都有一个实例变量(instance variable)用来保存某个Component类型的类的引用。 ConcreteDecorator:继承自Decorator,用来装饰Component类型的类(不能装饰抽象类),为其添加新的特性,可以在委托被装饰者的行为完成之前或之后的任意时候。 下面我们以星巴兹咖啡订单管理系统 管理、计算各种饮料的售价为例,对装饰者模式展开讨论。 设计思路及代码实现 继承 可能我们的第一印象就是继承。 首先定义一个咖啡基类 对于加糖的,加牛奶的,加摩卡的 ,加奶泡的,分别写一个子类继承 对于加糖,又加奶的写一个类,对于对于加糖,又摩卡的写一个类,对于对于加糖、又奶泡的写一个类,对于加糖,又加奶、摩卡的写一个类。

Odoo新API

别来无恙 提交于 2020-02-16 09:44:58
原文地址:http://www.cnblogs.com/ygj0930/p/7145594.html 新API的装饰器主要有以下几种: model,multi,one,constrains,depends,onchange,returns 一、one one的用法主要用于self为单一集合的情况,与之相对应的是multi。被one装饰的方法会返回一个list,其值是:[None] 二、multi 与one相对应,one要求self是单一记录,而multi则要求self是多个记录的合集。因此,常使用for—in语句遍历self。 三、model model要求self是一个记录集,返回一个集合列表。 四、contrains python约束。 五、depends depends 主要用于compute方法,depends就是用来标该方法依赖于哪些字段的。 六、onchange onchange的使用方法非常简单,就是当字段发生改变时,触发绑定的函数。 七、returns returns的用法主要是用来指定返回值的格式,它接受三个参数,第一个为返回值的model,第二个为向下兼容的method,第三个为向上兼容的method 新API中用于特殊方法的有: cr,cr_context,cr_uid,cr_uid_context,cr_uid_id,cr_uid_id_contet,cr

python自动化运维之路04

南楼画角 提交于 2020-02-12 10:44:48
装饰器 装饰器(decorator)是一种高级Python语法。装饰器可以对一个函数、方法或者类进行加工。 在Python中,我们有多种方法对函数和类进行加工,比如在Python闭包中,我们见到函数对象作为某一个函数的返回结果。 相对于其它方式,装饰器语法简单,代码可读性高。因此,装饰器在Python项目中有广泛的应用。 装饰器的应用场景:饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装 饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。 概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。 装饰器的规则: 1 def derector(function): 2 def wrapper(*args,**kwargs): 3 function(*args,**kwargs) 4 return wrapper 装饰器可以用def的形式定义,如上面代码中的decorator。装饰器接收一个可调用对象作为输入参数,并返回一个新的可调用对象。 装饰器新建了一个可调用对象,也就是上面的wrapper。 1.装饰器中如何传递参数? def outter1(Func): def wrapper(args): print("Before") Func(args) print(

设计模式:装饰者模式

|▌冷眼眸甩不掉的悲伤 提交于 2020-02-10 21:06:13
运行时扩展,比编译时继承威力更大 装饰对象,给爱用继承的人一个全新的设计眼界 星巴兹(Starbuzz)咖啡订单系统 1 (实锤了 是我买不起的样子) 星巴兹咖啡的扩张速度太快了,他们准备更新订单系统 他们之前设计的类是这样的 // 饮料类,店内所有饮料继承此类 abstract class Beverage { // 咖啡店的宣传标语 String description ; public void getDesString ( ) { System . out . println ( this . description ) ; } // 咖啡的花销,子类自己实现 public abstract void cost ( ) ; } 由于购买咖啡的时候会加入很多调料,比如牛奶、椰果等等,这样就组成了很多不同的咖啡种类,价格也就不一样 一旦调料多起来,类设计就会变成这样: 类爆炸!这简直是维护噩梦,如果牛奶价格上涨,所有加了牛奶的咖啡种类的 cost() 都要重写,这可太刺激了 利用实例变量和继承 为了不出现类爆炸的情况,我们使用实例变量和继承,在基类 Beverage 种添加代表每种调料的 boolean 类型实例变量 子类的 cost() 会在自己的花费上,判断是否有各个调料,有的话将调料的价格加上去 这会出现这样的问题: 调料价钱的改变会使我们改变现有代码 一旦出现新的调料