python装饰器
作者:互联网
1. 简介
Python中的装饰器是一种可以装饰其它对象的工具。类似于装饰模式,实际是对原有对象进行功能上的增强(原有对象可以是对象、函数、类)。其使用像java 的注解。
该工具本质上是一个可调用的对象(callable),所以装饰器一般可以由函数、类来实现。装饰器本身需要接受一个被装饰的对象作为参数,该参数通常为函数、方法、类等对象。装饰器需要返回一个对象,该对象可以是 经过处理的原参数对象、一个包装且类似原参数的对象;或者返回一个不相干内容。
基于@语法和函数闭包,将原函数封装在闭包中,然后将函数赋值为一个新的函数(内置函数),执行函数时再在内层函数中执行闭包中的原函数。可以在你改变函数内部代码和调用的前提下,实现在函数执行和执行拓展功能。
适用于多个函数系统统一在执行前后定义一些功能。
2. 简单使用
- 基于类实现装饰器,对函数进行增强
# 简单装饰器。 基于类实现装饰器,对函数进行增强
class wrap(object):
def __init__(self):
pass
def __call__(self, obj):
print("======1")
print(obj)
print("======2")
return obj
@wrap() # 等价于 foo = wrap(foo)
def foo():
print('hello decorator!')
print(foo())
结果:
======1
<function foo at 0x0000021FDBB9EF70>
======2
hello decorator!
None
- 基于函数实现装饰器,对函数进行增强
# 简单装饰器。 基于函数实现装饰器,对函数进行增强
def wrap(obj):
print("======1")
print(obj)
print("======2")
return obj
@wrap # 等价于 foo = wrap(foo)
def foo():
print('hello decorator!')
print(foo())
结果:
======1
<function foo at 0x000002171B1F1F70>
======2
hello decorator!
None
- 给被装饰的对象添加一个name 属性, 并且值设置为 张三
# 装饰器-给被装饰的对象添加一个name 属性, 并且值设置为 张三
def wrap(obj):
obj.name = '张三'
return obj
@wrap
class User:
def __int__(self):
pass
print(User.name) # => hello decorator!
print(User)
结果:
张三
<class '__main__.User'>
- 函数装饰器: 对传入的对象进行增强,增强后返回新的对象
# 函数装饰器: 对传入的对象进行增强,增强后返回新的对象
def outer(func):
def inner():
print("hello inner")
func()
return inner
@outer # foo = outer(foo)
def foo():
print('hello foo')
print(foo.__name__)
foo() # => hello foo
结果:
inner
hello inner
hello foo
- 对象方法装饰器。和普通的函数装饰器的区别是多了一个默认的self 参数
# desc: 对象方法装饰器。和普通的函数装饰器的区别是多了一个默认的self 参数
def outer(obj):
def inner(self):
print('hello inner')
obj(self)
return inner
class Zoo(object):
def __init__(self):
pass
@outer # => zoo = outer(zoo)
def zoo(self):
print('hello zoo')
zoo = Zoo()
print(zoo.zoo.__name__)
zoo.zoo()
结果:
inner
hello inner
hello zoo
- 类方法装饰器。 相当于对类进行增强
# desc: 类方法装饰器。 相当于对类进行增强
def outer(clss):
class Inner(object):
def __init__(self):
self.clss = clss()
def __getattr__(self, attr):
return getattr(self.clss, attr)
return Inner
@outer # Zoo = outer(Zoo)
class Zoo(object):
def __init__(self):
pass
def say(self):
print('hello world!')
zoo = Zoo()
print(zoo.__class__)
zoo.say()
结果:
<class '__main__.outer.<locals>.Inner'>
hello world!
- 特殊应用的装饰器,比如,类静态属性装饰器。 如下代码可以看出ratio 会作为一个属性,而不是方法
class Foo(object):
def __init__(self, height, weigth):
self.height = height
self.weigth = weigth
@property
def ratio(self):
return self.height / self.weigth
foo = Foo(176, 120)
print(foo.ratio)
自己实现:
class Prop(object):
def __init__(self, fget):
self.fget = fget
def __get__(self, instance, owner):
return self.fget(instance)
class Foo(object):
def __init__(self, height, weigth):
self.height = height
self.weigth = weigth
@Prop
def ratio(self):
return self.height / self.weigth
foo = Foo(176, 120)
print(foo.ratio)
- 装饰带参数和返回值的对象
# desc: 装饰带参数和返回值的对象
# def outer(func): # 函数装饰器
# def inner(x, y):
# print('hello inner')
# return func(x, y)
#
# return inner
def outer(func): # 函数装饰器
def inner(*args, **kwargs):
print('hello inner')
return func(*args, **kwargs)
return inner
@outer
def add(x, y):
return x + y
print(add(1, 4))
结果:
hello inner
5
- 装饰器本身带参数
# desc: 装饰器本身带参数
url_mapping = {}
def route(url):
def decorator(func): # 函数装饰器
url_mapping[url] = func
return func
return decorator
@route('/home')
def home():
print(1)
pass
@route('/index')
def index():
print(2)
pass
print(url_mapping)
结果:
{'/home': <function home at 0x000001B16D480D30>, '/index': <function index at 0x000001B16D48F040>}
标签:__,python,self,print,foo,装饰,def 来源: https://www.cnblogs.com/qlqwjy/p/16572879.html