Reputation: 4238
In a code below i have written depends decorator which just takes as a parametr some functions and call them before calling decorated function. So when when i use this script i get on output:
using f
using g
using f
using h
But now there comes my question. How to do it not to duplicate dependencies? So when i use h(), f() will be called just once? I tried to remove duplicates form functs, but for example for h() it's containing wapper and f(). Should I collect them in other way?
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()
Upvotes: 2
Views: 947
Reputation: 880607
Python already has something like this already built into its super
calling mechanism. However, to take advantage of super
, you have to turn your dependencies into base classes:
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
Upvotes: 3
Reputation: 41873
You need to check wether any of the dependency function has been decorated in this way, and exclude their dependencies from the ones for the currently decorated function.
This check needs to be done recursively.
It becomes much more difficult if you also use other decorators.
I really wonder why and how this construct is used.
Upvotes: 0
Reputation: 26204
You need to remember processed dependencies globally, for example in a class variable, see depends.done
here:
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()
Upvotes: 1