今天在写校验时间的代码时被要求用装饰器,我看了看我已经写好的代码
class StartDeploy(object):
@classmethod
def is_ban_time(cls):
now_time = datetime.now().time()
time_list = db.get_list('ACTIVITY_TIME:CAN NOT DEPOLY')
if time_list:
for time_str in time_list:
_,start_time, end_time = time_str.split(',')
start_time = datetime.strptime(start_time,'%H:%M:%S').time()
end_time = datetime.strptime(end_time,'%H:%M:%S').time()
# 比较时间
if start_time <= now_time <= end_time:
return True
return False
@classmethod
def start_deploy(cls):
flag = True
if cls.is_ban_time():
while flag:
input_value = raw_input("当前时间在禁止上线时间内,是否强制上线 (y/n):")
if input_value.lower().split() == 'y':
flag = False
elif input_value.lower().split() == 'n':
return False
return True
心想装饰器确实是个不错的选择,不过我这个类有没有办法改成装饰器呢?我记得我以前看过一本书叫 Effect Python 提到过类装饰器,但具体怎么实现不会,今天就试试吧,也不想改成函数实现的装饰器了。
首先,类初始化一个对象要经过两步
- 执行__new__构造方法构造一个 cls 对象
- 执行__init__初始化一个 self 对象
也就是说在类的对象创建完成之前,通过重写以上两个方法我们可以干预它的创建过程
这有什么用呢?
我们可以在初始化对象的时候,将需要被装饰的函数传进来
class StartDeploy(object):
def __init__(self, func):
self.__func = func
def func():
print('in func')
好,那么我们得在执行 func 之前进行时间校验,有没有办法去控制执行顺序?
在 python 中有许多魔法方法,包括下面这个:
def __call__(self, *args, **kwargs):
pass
在调用某个对象的方法时,__call__是调用的入口,即我们可以在执行任意一个对象方法之前,做一些操作,下面有个例子
class deco:
def __init__(self, func):
self.__func = func
def w(self):
print('in w')
def printf(self):
print('in printf')
self.w()
def __call__(self, *args, **kwargs):
self.printf()
self.__func()
@deco
def ceshi():
print('in func')
ceshi()
所以基于以上特性,我们的类装饰器也就完成了
class StartDeploy(object):
def __init__(self, func):
self.__func = func
def __call__(self, *args, **kwargs):
if not self.start_deploy():
return
self.__func()
@classmethod
def is_ban_time(cls):
now_time = datetime.now().time()
time_list = db.get_list('ACTIVITY_TIME:CAN NOT DEPOLY')
if time_list:
for time_str in time_list:
_,start_time, end_time = time_str.split(',')
start_time = datetime.strptime(start_time,'%H:%M:%S').time()
end_time = datetime.strptime(end_time,'%H:%M:%S').time()
# 比较时间
if start_time <= now_time <= end_time:
return True
return False
@classmethod
def start_deploy(cls):
flag = True
if cls.is_ban_time():
while flag:
input_value = raw_input("当前时间在禁止上线时间内,是否强制上线 (y/n):")
if input_value.lower().split() == 'y':
flag = False
elif input_value.lower().split() == 'n':
return False
return True
装饰器相关的内容还挺多的,以后会慢慢更新
- 带参数的装饰器
- 多个装饰器嵌套的执行顺序
- 给类添加装饰器
- 闭包的概念