比如有下面如下的代码,每个函数都需要判断debug的是否为True,而默认的debug为False

def a(x,debug=False):

if debug:

print('calling a')

def b(x,y,z,debug=False):

if debug:

print('calling b')

def c(x,y,debug=False):

if debug:

print('calling c')

上面的代码可以编写一个装饰器为被包装的函数添加额外的参数来简化,但是添加的参数不能影响到该函数已有的调用约定。定义如下的一个装饰器

def optional_debug(func):

@wraps(func)

def wrapper(*args,debug=False,**kwargs):

if debug:

print('Calling',func.__name__)

return func(*args,**kwargs)

return wrapper

@optional_debug

def spam(a,b):

print(a,b)

spam(1,2)

>>>1,2

spam(1,2,debug=True)

>>>Calling spam

1,2

利用装饰器给类定义打补丁

我们想检查一部分类的定义,以此来修改类的行为,但是不想通过继承或者元类的方式来做

我们可以用一个类装饰器重写__getattribute__

def log_getattribute(cls):

print(cls)

orig_getattribute=cls.__getattribute__

def new_getattribute(self,name):

print('geting:',name)

return orig_getattribute(self,name)

cls.__getattribute__=new_getattribute

return cls

@log_getattribute

class A:

def __init__(self,x):

self.x=x

def spam(self):

pass

(1) 首先通过orig_getattribute=cls.__getattribute__将初始的__getattribute__方法赋值给orig_getattribute,便于在new_getattribute调用

(2) 然后通过cls.__getattribute__=new_getattribute将类的__getattribute__赋值为new_getattribute,这样在类中调用__getattribute__的时候,其实是调用的new_getattribute

(3) 最后return cls

a=A(42)

print(a.x)

运行结果:

geting: x

42

@font-face { font-family: "Times New Roman"; }@font-face { font-family: "宋体"; }p.MsoNormal { margin: 0pt 0pt 0.0001pt; text-align: justify; font-family: "Times New Roman"; font-size: 10.5pt; }span.msoIns { text-decoration: underline; color: blue; }span.msoDel { text-decoration: line-through; color: red; }div.Section0 { }

python cookbook第三版学习笔记十九:未包装的函数添加参数的更多相关文章

  1. python cookbook第三版学习笔记十:类和对象(一)

    类和对象: 我们经常会对打印一个对象来得到对象的某些信息. class pair:     def __init__(self,x,y):         self.x=x         self. ...

  2. python cookbook第三版学习笔记十六:抽象基类

    假设一个工程中有多个类,每个类都通过__init__来初始化参数.但是可能有很多高度重复且样式相同的__init__.为了减少代码.我们可以将初始化数据结构的步骤归纳到一个单独的__init__函数中 ...

  3. python cookbook第三版学习笔记十五:property和描述

    8.5 私有属性: 在python中,如果想将私有数据封装到类的实例上,有两种方法:1 单下划线.2 双下划线 1 单下划线一般认为是内部实现,但是如果想从外部访问的话也是可以的 2 双下划线是则无法 ...

  4. python cookbook第三版学习笔记十二:类和对象(三)创建新的类或实例属性

    先介绍几个类中的应用__getattr__,__setattr__,__get__,__set__,__getattribute__,. __getattr__:当在类中找不到attribute的时候 ...

  5. python cookbook第三版学习笔记十四:类和对象(五)代理类以及内存回收

    代理类: 代理类的作用其实有继承有些类似,如果你想将某个实例的属性访问代理到内部另外一个实例中去,可以用继承也可以用代理.来看下代理的应用: class A:     def spam(self,x) ...

  6. python cookbook第三版学习笔记十八:可由用户修改的装饰器

    定义一个属性可由用户修改的装饰器: 在前面的介绍中使用装饰器来包装函数,这一章来介绍下如何让用户调整装饰器的属性. 首先来看下代码: from functools import wraps,parti ...

  7. python cookbook第三版学习笔记二十:可自定义属性的装饰器

    在开始本节之前,首先介绍下偏函数partial.首先借助help来看下partial的定义 首先来说下第一行解释的意思: partial 一共有三个部分: (1)第一部分也就是第一个参数,是一个函数, ...

  8. python cookbook第三版学习笔记二十一:利用装饰器强制函数上的类型检查

    在演示实际代码前,先说明我们的目标:能对函数参数类型进行断言,类似下面这样: @typeassert(int, int) ... def add(x, y): ...     return x + y ...

  9. python cookbook第三版学习笔记九:函数

    接受任意数量参数的函数. 当传入函数的参数个数很多的时候,在函数定义的时候不需要为每一个参数定义一个变量,可以用*rest的方式来包含多余的参数. 如下面的代码,*rest包含了2,3,4这3个参数. ...

随机推荐

  1. 100多道经典的JAVA面试题及答案解析

    面向对象编程(OOP) Java是一个支持并发.基于类和面向对象的计算机编程语言.下面列出了面向对象软件开发的优点: 代码开发模块化,更易维护和修改. 代码复用. 增强代码的可靠性和灵活性. 增加代码 ...

  2. STL学习笔记(移除性算法)

    本节所列的算法是根据元素值或某一准则,在一个区间内移除某些元素. 这些算法并不能改变元素的数量,它们只是将原本置于后面的“不移除元素”向前移动,覆盖那些被移除的元素. 这些算法都返回逻辑上的新终点 移 ...

  3. 操作REDIES

    import redis r=redis.Redis(host='118.XX.XX.XXX',password='XXXXXXX9*',db=1,port=6379) # 增删改查r.set('jd ...

  4. NUTCH2.3 hadoop2.7.1 hbase1.0.1.1 solr5.2.1部署(三)

     Precondition: hadoop 2.7.1 hbase 0.98.13 solr 5.2.1 / Apache Solr 4.8.1 http://archive.apache.org ...

  5. linux的用户、群组

    1.      用户及passwd文件 1)      掌握/etc/passwd文件的功能:存储所有用户的相关信息,该文件也被称为用户信息数据库(Database). 2)      /etc/pa ...

  6. An error occurred while searching for implementations of method

    1:在我安装完scala的插件后,在打开方法的实现类(open implementactions)的时候,抛出这个异常,后来发现这个异常是因为我的scala的插件跟我eclipse版本不兼容导致的. ...

  7. nginx反向代理做cache配置

    前序:请耐性子看完,前面的这个配置可以达到按后缀名进行缓存,但无法被purge.后面的配置可以被purge.具体实施方案按个人情况而定. 需要第三方的ngx_cache_purge模块:wget ht ...

  8. linux下tomcat6无法显示图片验证码 少了图形插件

    linux下tomcat6无法显示图片验证码(windows下显示正常) 原创 2015年10月20日 10:31:47 3526 linux下tomcat6无法显示图片验证码(windows下显示正 ...

  9. 如何在struts2中实现下载?

    <a href="${pageContext.request.contextPath}/download?filename="+filename>点击下载</a& ...

  10. gen_server2 与gen_server的对比

    在erlang杀手级应用rabbitmq中,不难发现,有一个gen_server2.erl模块.而在rabbitmq中,gen_server2.erl是对gen_server.erl模块的重写. Ra ...