一、什么是装饰器
- 也是一种函数
- 可以接收函数作为参数
- 可以返回函数
- 接收一个函数,内部对其处理,然后返回一个新函数,动态的增强函数功能
- 将c函数在a函数中执行,在a函数中可以选择执行或者不执行c函数,也可以对c函数的结果进行二次加工处理
def a():
def b():
print('hello')
b()
a()
b() # 错误
装饰器的用法,相当于把b函数放到a函数中,在a函数的内部调用b函数,然后在最外层调用a函数。
二、装饰器的定义
语法规则如下
def out(func_args): # 外围函数
def inter(*args, **kwargs): # 内嵌函数
return func_args(*args, **kwargs)
return inter # 外围函数返回内嵌函数
- 将被调用的函数直接作为参数传入装饰器的外围函数括弧
- 将装饰器与被调用函数绑定在一起
- @符号+装饰器函数放在被调用函数的上一行,被调用的函数正常定义,只需要直接调用被执行函数即可
方法一
def a(func):
def b(*args, **kwargs):
return func(*args, **kwargs)
return b
def c(name):
print(name)
a(c)('xiaom')
方法二
@a
def c(name):
print(name)
c('xm')
装饰器的案例
# coding:utf-8
def check_str(func):
print('func:', func)
def inner(*args, **kwargs):
print('args:', args, kwargs)
result = func(*args, **kwargs)
if result == 'ok':
return 'result is %s' % result
else:
return 'result is failed:%s' % result
return inner
@check_str
def test(data):
return data
result = test(data='no')
print(result)
result = test(data='ok')
print(result)
三、类中的装饰器
1. classmethod的功能
- 将类函数可以不经过实例化而直接被调用
用法:
@classmethod
def func(cls, ...):
do
参数介绍:
cls 替代普通类函数中的self,
变为cls,代表当前操作的是类
class Test(object):
@classmethod
def add(cls, a, b):
return a + b
Test.add(1, 2)
class Test(object):
def __init__(self, a): # 构造函数
self.a = a
def run(self):
print('run')
self.dump()
@classmethod
def dump(cls):
print('dump')
# cls.run()
t = Test('a')
t.run()
# Test.dump()
- 上述代码主要验证一件事情,那就是普通的self类函数可以调用classmethod装饰器函数,但是我们的classmethod装饰器函数不能调用普通的self类函数。
2. staticmethod的功能
-将类函数可以不经过实例化而直接被调用,被该装饰器调用的函数不许传递self或cls参数,且无法在该函数内调用其他类函数或类变量。
用法:
@staticmethod
def func(...):
do
参数介绍:
函数体内无cls或者self参数
class Test(object):
@staticmethod
def add(a, b):
return a + b
Test.add(1, 2)
class Test(object):
def __init__(self, a): # 构造函数
self.a = a
def run(self):
print('run')
self.dump()
self.sleep()
@classmethod
def dump(cls):
print('dump')
# cls.run()
@staticmethod
def sleep():
print('I wanna sleep')
t = Test('a')
t.run()
Test.sleep()
t.sleep()
t.dump()
- 第一点,被该装饰器调用的函数不可以传递self或者cls参数。
- 第二点,普通的self函数可以调用我们的staticmethod装饰器函数,但是我们staticmethod装饰器函数不可以调用我们普通的self函数。
3. property的功能
- 将类函数的执行免去括弧,类似于调用属性(变量)
用法:
@property
def func(self):
do
参数介绍:
一般遵照定义,不对函数传参。
如果一定要传参的话进行重写property调用的函数,函数名必须要一样,而且需要重写装饰器,在原有函数名的基础上加".setter",这样就可以传入参数了。
class Test(object):
def __init__(self, name):
class Test1(object):
def __init__(self, name):
self.__name = name
@property
def name(self):
return self.__name
@name.setter
def name(self, value):
self.__name = value
t1 = Test1(name='xm')
print(t1.name)
t1.name = 'gg'
print(t1.name)