Python--进阶处理9
# =========================第九章:元编程============================= # ----------------在函数上添加包装器-----------------------
# 在函数上添加一个包装器,增加额外的操作处理(比如日志、计时等)
import time
from functools import wraps def timethis(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(func.__name__, end - start)
return result
return wrapper @timethis
def countdown(n):
while n > 0:
n -= 1 countdown(10000000)
# 一个装饰器就是一个函数,它接受一个函数作为参数并返回一个新的函数
# 任何时候定义装饰器的时候,都应该使用functools 库中的@wraps 装饰器来注解底层包装函数
# 在编写装饰器的时候复制元信息是一个非常重要的部分。如果你忘记了使用@wraps,那么你会发现被装饰函数丢失了所有有用的信息 from functools import wraps
import logging def logged(level, name=None, meaasge=None):
def decorate(func):
logname = name if name else func.__module__
log = logging.getLogger(logname)
logmsg = meaasge if meaasge else func.__name__ @wraps(func)
def wrapper(*args, **kwargs):
log.log(level, logmsg)
return func(*args, **kwargs)
return wrapper
return decorate @logged(logging.DEBUG)
def add(x, y):
return x + y """
最外层的函数logged()接受参数并将它们作用在内部的装饰器函数上面。
内层的函数decorate() 接受一个函数作为参数,
然后在函数上面放置一个包装器。
这里的关键点是包装器是可以使用传递给logged() 的参数的
""" from inspect import signature
from functools import wraps def typeassert(*ty_args, **ty_kwargs):
def decorate(func):
if not __debug__:
return func sig = signature(func)
bound_types = sig.bind_partial(*ty_args, **ty_kwargs).arguments @wraps(func)
def wrapper(*args, **kwargs):
bound_values = sig.bind(*args, **kwargs)
for name, value in bound_values.arguments.items():
if name in bound_types:
if not isinstance(value, bound_types[name]):
raise TypeError('Argument {} must be {}'.format(name, bound_types[name]))
return func(*args, **kwargs)
return wrapper
return decorate
"""
可以看出这个装饰器非常灵活,既可以指定所有参数类型,也可以只指定部分。
并且可以通过位置或关键字来指定参数类型
"""
@typeassert(int, z=int)
def spam(x, y, z=24):
print(x, y, z) spam(1, 2, 3)
spam(1, '2', 3)
# spam(1, 'a', 'b')
# ---------------------------------------------------------------------------------------------- # ------------------将装饰器定义为类的一部分--------------------------------
from functools import wraps class A:
# Decorator as an instance method
def decorator1(self, func):
@wraps(func)
def wrapper(*args, **kwargs):
print('Decorator 1')
return func(*args, **kwargs)
return wrapper # Decorator as a class method
@classmethod
def decorator2(cls, func):
@wraps(func)
def wrapper(*args, **kwargs):
print('Decorator 2')
return func(*args, **kwargs)
return wrapper
# 一个是实例调用,一个是类调用
a = A()
@a.decorator1
def spam():
pass @A.decorator2
def grok():
pass
# ----------------------------------------------------------------------- # 将装饰器定义为类
# 为了将装饰器定义成一个实例,你需要确保它实现了__call__() 和__get__() 方法
import types
from functools import wraps class Profiled:
def __init__(self, func):
wraps(func)(self)
self.ncalls = 0 def __call__(self, *args, **kwargs):
self.ncalls += 1
return self.__wrapped__(*args, **kwargs) def __get__(self, instance, cls):
if instance is None:
return self
else:
return types.MethodType(self, instance) @Profiled
def add(x, y):
return x + y class Spam:
@Profiled
def bar(self, x):
print(self, x)
# --------------------------------------------------------------------------------
# ?????????????????????????????332
Python--进阶处理9的更多相关文章
- Python进阶:函数式编程实例(附代码)
Python进阶:函数式编程实例(附代码) 上篇文章"几个小例子告诉你, 一行Python代码能干哪些事 -- 知乎专栏"中用到了一些列表解析.生成器.map.filter.lam ...
- Python进阶 - 对象,名字以及绑定
Python进阶 - 对象,名字以及绑定 1.一切皆对象 Python哲学: Python中一切皆对象 1.1 数据模型-对象,值以及类型 对象是Python对数据的抽象.Python程序中所有的数据 ...
- Python进阶-继承中的MRO与super
Python进阶-继承中的MRO与super 写在前面 如非特别说明,下文均基于Python3 摘要 本文讲述Python继承关系中如何通过super()调用"父类"方法,supe ...
- Python进阶 - 命名空间与作用域
Python进阶 - 命名空间与作用域 写在前面 如非特别说明,下文均基于Python3 命名空间与作用于跟名字的绑定相关性很大,可以结合另一篇介绍Python名字.对象及其绑定的文章. 1. 命名空 ...
- python进阶学习笔记(一)
python进阶部分要学习的内容: 学习目标: 1.函数式编程 1.1,什么是函数式编程 函数式编程是一种抽象计算的编程模式 不同语言的抽象层次不同: 函数式编程的特点: python支持的函数式编程 ...
- 【python进阶】详解元类及其应用2
前言 在上一篇文章[python进阶]详解元类及其应用1中,我们提到了关于元类的一些前置知识,介绍了类对象,动态创建类,使用type创建类,这一节我们将继续接着上文来讲~~~ 5.使⽤type创建带有 ...
- 【python进阶】Garbage collection垃圾回收2
前言 在上一篇文章[python进阶]Garbage collection垃圾回收1,我们讲述了Garbage collection(GC垃圾回收),画说Ruby与Python垃圾回收,Python中 ...
- Python进阶 函数式编程和面向对象编程等
函数式编程 函数:function 函数式:functional,一种编程范式.函数式编程是一种抽象计算机的编程模式. 函数!= 函数式(如计算!=计算机) 如下是不同语言的抽象 层次不同 高阶函数: ...
- 【python进阶】深入理解系统进程2
前言 在上一篇[python进阶]深入理解系统进程1中,我们讲述了多任务的一些概念,多进程的创建,fork等一些问题,这一节我们继续接着讲述系统进程的一些方法及注意点 multiprocessing ...
- Python进阶:如何将字符串常量转化为变量?
前几天,我们Python猫交流学习群 里的 M 同学提了个问题.这个问题挺有意思,经初次讨论,我们认为它无解. 然而,我认为它很有价值,应该继续思考怎么解决,所以就在私密的知识星球上记录了下来. 万万 ...
随机推荐
- Linux Kernel源码浏览
https://www.kernel.org/http://lxr.linux.no/
- CControlLayer
#ifndef __CONTROLLAYER_H__ #define __CONTROLLAYER_H__ #include "XWidget.h" class CMapDialo ...
- A+P+M+W
安装之前先做个目录的安排, D盘根目录建立”Dev”文件夹,在文件夹下建立: Php Apache Mysql 三个文件夹 所需软件: 0. 安装Apache的前必须安装VC11 vcredis ...
- try与catch
首先要清楚,如果没有try的话,出现异常会导致程序崩溃.而try则可以保证程序的正常运行下去,比如说:try{int i = 1/0;}catch(Exception e){........}一个计算 ...
- 关于Context
Context字面意思是上下文,位于framework package的android.content.Context中,其实该类为LONG型,类似Win32中的Handle句柄.很多方法需要通过 C ...
- 删除节点removeChild()
http://www.imooc.com/code/1700 删除节点removeChild() removeChild() 方法从子节点列表中删除某个节点.如删除成功,此方法可返回被删除的节点,如失 ...
- 深入学习HttpClient(一)扩展额外的功能
HttpClient作为.net4.5新增的Http库除了对于async/await形式的异步支持外,还向我们展示了其强大的扩展能力. [类库的设计] 让我们先看下Httpclient的设计图: 图中 ...
- hdu 5384 Danganronpa(字典树)
题意: f(A,B)表示:B在A中作为子串出现的次数. 题目给出n个证据,m个子弹 Ai是证据.Bi是子弹.题目问:全部Bi对每一个Ai造成的伤害是多少,即每一个Bi在Ai中出现的次数总和. 解析: ...
- 示例 - 如何在Console应用程序中应用SpiderStudio生成的DLL?
以前面生成的XML/JSON互转DLL为例, 我们写一个Console Appliction来做这件事情, 步骤如下: 1. 创建Console Project 2. 引入www.utilities_ ...
- gch文件学习
今晚学习友元函数的时候一点一点的在写一个头文件和一个源文件,中间g++ test.h了一下,无意中就生成了test.h.gch文件.后来修改了头文件的内容,但是不知道为什么一直各种出错,一番折腾之后才 ...