Python
369 浏览 5 years, 4 months
10.1 被装饰对象
版权声明: 转载请注明出处 http://www.codingsoho.com/被装饰对象
被装饰对象可以是下面三种
- 函数
- 类
- 类方法
函数装饰器 - 对函数进行装饰
它改变函数执行时的行为,通过下面方法来改变
- 在函数
定义
时添加额外动作 - 在原函数
运行前后
增加额外的代码 调用
时改变传递给原函数的参数
看下面代码
#decor
def hello(name):
print("Hello {}".format(name))
hello = decor(hello)
装饰是一种重新绑定行为,
高阶函数
- 函数式编程的概念
- 函数能够作为参数被别的函数使用
- 函数的返回值是其他函数
下面是一个对函数进行装饰的例子
def wrapper_decor(f):
def wrapper(x):
print("Call original function")
f(x)
print("Call original function done")
return wrapper
@wrapper_decor
def hello(name):
print("How are you? {}".format(name))
净效果:
hello = wrapper_decor( hello)
装饰是一种重新绑定行为
装饰动作发生的时机:
- 被装饰对象定义时
- 被装饰对象执行时
上面的例子装饰动作就是发生在执行时
下面例子中,装饰器并没有执行被装饰函数,这个装饰过程在定义时就已经完成
registry = set()
print registry #(1)
def register(func):
registry.add(func) #(2)
return func
@register
def Apple():
print "Apple"
@register
def Banana():
print "banana"
print registry
一个用户函数注册的装饰器。只为管理函数,并不修改函数的执行行为
set([])
- 将func添加到registry中,但func函数本身并不会被执行
set([<function Banana at 0x02575D70>, <function Apple at 0x02575BF0>])
对类进行装饰
@decor
class Foo():
pass
Foo = decor(Foo)
下面是一个例子:
def context_decor(cls):
def setup(self):
print("Setup...")
def teardown(self):
print("Tear down")
cls.setup, cls.teardown = setup, teardown
return cls
@context_decor
class TestCase():
def __init__(self, name):
self.name = name
def test_checkFunction(self):
print("Inside test case: test_checkFunction")
通过继承修改类的定义,改变其行为
也可以用下面的方法
def context_decor(cls):
class ProxyCls(cls):
def setup(self):
print("Setup...")
def teardown(self):
print("Tear down")
return ProxyCls
@context_decor
class TestCase():
def __init__(self, name):
self.name = name
def test_checkFunction(self):
print("Inside test case: test_checkFunction")
对类方法装饰
class Foo():
@decor
def hello(self, name):
print("Hello {}".format(name))
Foo.hello = decor(Foo.hello) # Name re-binding
- 参数传递问题 - self
- self参数会被正确的传入,即使类方法被装饰过
对类方法装饰的例子
def wrapper_decor(f):
def wrapper(x):
print("Change behavior of original function")
print("Call original function")
f(x)
print("Call originnal function done")
return wrapper
class Foo():
@wrapper_decor
def bar(self, x):
print(x)