html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video { margin: 0; padding: 0; border: 0 }
body { font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 14px; line-height: 1.6; color: #333; background-color: #fff; padding: 20px; max-width: 960px; margin: 0 auto }
body>*:first-child { margin-top: 0 !important }
body>*:last-child { margin-bottom: 0 !important }
p,blockquote,ul,ol,dl,table,pre { margin: 15px 0 }
h1,h2,h3,h4,h5,h6 { margin: 20px 0 10px; padding: 0; font-weight: bold }
h1 tt,h1 code,h2 tt,h2 code,h3 tt,h3 code,h4 tt,h4 code,h5 tt,h5 code,h6 tt,h6 code { font-size: inherit }
h1 { font-size: 28px; color: #000 }
h2 { font-size: 24px; border-bottom: 1px solid #ccc; color: #000 }
h3 { font-size: 18px }
h4 { font-size: 16px }
h5 { font-size: 14px }
h6 { color: #777; font-size: 14px }
body>h2:first-child,body>h1:first-child,body>h1:first-child+h2,body>h3:first-child,body>h4:first-child,body>h5:first-child,body>h6:first-child { margin-top: 0; padding-top: 0 }
a:first-child h1,a:first-child h2,a:first-child h3,a:first-child h4,a:first-child h5,a:first-child h6 { margin-top: 0; padding-top: 0 }
h1+p,h2+p,h3+p,h4+p,h5+p,h6+p { margin-top: 10px }
a { color: #4183C4; text-decoration: none }
a:hover { text-decoration: underline }
ul,ol { padding-left: 30px }
ul li>:first-child,ol li>:first-child,ul li ul:first-of-type,ol li ol:first-of-type,ul li ol:first-of-type,ol li ul:first-of-type { margin-top: 0px }
ul ul,ul ol,ol ol,ol ul { margin-bottom: 0 }
dl { padding: 0 }
dl dt { font-size: 14px; font-weight: bold; font-style: italic; padding: 0; margin: 15px 0 5px }
dl dt:first-child { padding: 0 }
dl dt>:first-child { margin-top: 0px }
dl dt>:last-child { margin-bottom: 0px }
dl dd { margin: 0 0 15px; padding: 0 15px }
dl dd>:first-child { margin-top: 0px }
dl dd>:last-child { margin-bottom: 0px }
pre,code,tt { font-size: 12px; font-family: Consolas, "Liberation Mono", Courier, monospace }
code,tt { margin: 0 0px; padding: 0px 0px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8 }
pre>code { margin: 0; padding: 0; white-space: pre; border: none; background: transparent }
pre { background-color: #f8f8f8; border: 1px solid #ccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px }
pre code,pre tt { background-color: transparent; border: none }
kbd { background-color: #DDDDDD; background-image: linear-gradient(#F1F1F1, #DDDDDD); background-repeat: repeat-x; border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD; border-style: solid; border-width: 1px; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; line-height: 10px; padding: 1px 4px }
blockquote { border-left: 4px solid #DDD; padding: 0 15px; color: #777 }
blockquote>:first-child { margin-top: 0px }
blockquote>:last-child { margin-bottom: 0px }
hr { clear: both; margin: 15px 0; height: 0px; overflow: hidden; border: none; background: transparent; border-bottom: 4px solid #ddd; padding: 0 }
table th { font-weight: bold }
table th,table td { border: 1px solid #ccc; padding: 6px 13px }
table tr { border-top: 1px solid #ccc; background-color: #fff }
table tr:nth-child(2n) { background-color: #f8f8f8 }
img { max-width: 100% }
python装饰器
定义:本质是函数,(装饰其他函数)就是为其他函数添加附加功能
原则:
1. 不能修改被装饰的函数的源码
2. 不能修改原函数的调用方式
知识储备:1. 函数即变量函数执行的时候解释器从上向下执行2. 高阶函数
a. 把一个函数名当作实参传递给另一个函数(可以做到在不修改函数源码的情况下,为其添加功能) b. 返回值中包含函数名3. 嵌套函数
当装饰器需要参数需要三层嵌套,不需要参数两层嵌套
装饰器可能的应用
作为一个函数
创造装饰器最简单的方法就是写一个函数,返回包装原始函数调用的一个子函数
def mydecorator(function): def wrapped(*args,**kwargs): #调用原始函数之前做的操作 result=function(*args,**kwargs) #调用原始函数之后做点什么 #返回结果 return result #返回wrapper作为装饰函数 return wrapped
作为一个类
大多数情况装饰器总是用函数实现,但在某些情况下使用类会更好。如果装饰器需要复杂的参数化或者依赖特定状态,就会使用装饰类
通用模式
class DecoratorAsClass: def __init__(self,function): self.function=function def __call__(self,*args,**kwargs): #在调用原始函数指点,做点什么 result=self.function(*args,**kwargs) #在调用原始函数之后做点什么 #返回函数执行结果 return result@DecoratorAsClassdef hello(): print(‘hello‘)hello()
参数化装饰器
实际使用装饰器需要使用参数化的装饰器。类装饰器不用说,初始化的时候就可以传入参数。如果是函数作装饰器的话,就需要第二层包装。如需要多次执行一个原始函数,而重复次数通过装饰器参数给定,下面是示例代码
def repeat(number=3): """多此执行装饰函数,返回最后一次执行结果 参数名为 number:重复次数,默认为3 """ def erceng_decorator(function): def wrapper(*args,**kwargs): result=None for _ in range(number): result=function(*args,**kwargs) return result return ercent_decorator@repeat(2)def hello(): print("hello")hello()hellohello
在使用参数化装饰器的时候参数有默认值,但名字后面必须加括号,否则会报错
保存内省的装饰器
在使用装饰器常见的问题就是无法保存原始函数的元数据(文档字符串和函数名),装饰器组合创建了一个新的函数,返回一个新的对象,但没有考虑到原始函数的标识。这回给调试造成麻烦,无法找寻原始函数,也会破坏自动生成文档的工具,无法访问原始函数的文档字符串
def dummy_dec(function):... def wrapped(*args,**kwargs):... """包装函数内部文档。"""... return wrapped @dummy_dec... def function_important_doc():... """这是重要文档""" function_important_doc.__name__‘wrapped‘>>> function_important_doc.__doc__‘包装函数内部文档。‘
如上所示,原始函数的名字和文档都被修改了,解决这个问题也很容易,使用functools模块内置的wraps()装饰器:
from functools import wraps def chuli_dec(function): @wraps(function) def wrapper(*args,**kwargs): """包装函数文档""" return function(*args,**kwargs) return wrapper@chuli_decdef func_import_doc(): """这是重要文档"""print(func_import_doc.__name__)print(func_import_doc.__doc__) func_import_doc这是重要文档
像上面处理这就对了
原文地址:https://www.cnblogs.com/dcotorbool/p/8158008.html