2

在下面的代码中,我编写了依赖装饰器,它只是将一些函数作为参数并在调用装饰函数之前调用它们。所以当我使用这个脚本时,我会得到输出:

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()
4

3 回答 3

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
于 2013-04-16T11:48:14.263 回答
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()
于 2013-04-16T11:25:13.133 回答
0

您需要检查是否有任何依赖函数已以这种方式装饰,并从当前装饰函数的依赖项中排除它们的依赖关系。

此检查需要递归完成。

如果您还使用其他装饰器,这将变得更加困难。

我真的很想知道为什么以及如何使用这种结构。

于 2013-04-16T14:05:44.133 回答