在下面的代码中,我编写了依赖装饰器,它只是将一些函数作为参数,并在调用装饰函数之前调用它们。因此,当我使用这个脚本时,我得到输出:
using f
using g
using f
using h
但现在我的问题出现了。怎么做不重复依赖?所以当我使用h()时,f()只会被调用一次?我试图删除重复形式的功能,但例如对于h()它包含wapper和f()。我应该以其他方式收集它们吗?
class depends(object):
functs = []
def __init__(self, *f):
self.functs = []
for i in f:
self.functs.append(i)
def __call__(self, fun):
def wrapper():
for i in self.functs:
i()
return fun()
return wrapper
def f():
print 'using f'
@depends(f)
def g():
print 'using g'
@depends(g, f)
def h():
print 'using h'
h()
答案 0 :(得分:3)
Python已经在其super
调用机制中内置了类似的东西。但是,要利用super
,您必须将依赖项转换为基类:
def depends(*deps):
def deco(func):
def __new__(self):
super(Dependency, self).__new__(self)
return func()
Dependency = type('Dependency', deps, {'__new__': __new__})
return Dependency
return deco
@depends(object)
def f():
print 'using f'
@depends(f)
def g():
print 'using g'
@depends(g, f)
def h():
print 'using h'
h()
# using f
# using g
# using h
答案 1 :(得分:1)
您需要全局记住已处理的依赖项,例如在类变量中,请参阅此处的depends.done
:
class depends(object):
done = []
def __init__(self, *f):
self.functs = f
def __call__(self, fun):
def wrapper():
for i in self.functs:
if i not in depends.done:
i()
depends.done.append(i)
return fun()
return wrapper
def f():
print 'using f'
@depends(f)
def g():
print 'using g'
@depends(g, f)
def h():
print 'using h'
h()
答案 2 :(得分:0)
你需要检查是否已经以这种方式修饰了任何依赖函数,并从当前修饰函数的依赖项中排除它们的依赖关系。
这项检查需要递归完成。
如果你也使用其他装饰器会变得更加困难。
我真的很想知道为什么以及如何使用这个结构。