Python 更改子类中的装饰器参数

Python 更改子类中的装饰器参数,python,python-2.x,python-decorators,Python,Python 2.x,Python Decorators,不确定这是否是一个恰当的问题,但问题是 我有一个记忆装饰器(作为类实现)。decorator接受一个参数,该参数是缓存的大小。我希望我的DB模型类每个都有一个搜索方法,因此我编写了一个mixin(我认为它是一个mixin) 在我的模型中 class ModelA(Base,SearchMixin): foo = Column() bar = Column() #And so on 现在,我可以执行ModelA.search(foo=x,bar=y),如果以前曾询问过

不确定这是否是一个恰当的问题,但问题是

我有一个记忆装饰器(作为类实现)。decorator接受一个参数,该参数是缓存的大小。我希望我的DB模型类每个都有一个搜索方法,因此我编写了一个mixin(我认为它是一个mixin)

在我的模型中

class ModelA(Base,SearchMixin): 
    foo = Column()
    bar = Column() 
    #And so on
现在,我可以执行
ModelA.search(foo=x,bar=y)
,如果以前曾询问过相同的查询,那么记忆装饰器就会工作并从缓存返回

问题是,对于某些型号,我需要更改某些搜索的缓存大小(通过
SearchMixin
中的default
100
)。我可以用一个不同的参数重新编写搜索函数给decorator

class ModelB(Base): 
    @classmethod
    @memoized(5)
    def search(cls,session,**kwargs): 
        #Search method for my modelB
但这违背了编写mixin(消除代码重复)的目的

理想情况下我想要的是

class ModelB(Base,SearchMxin): 
    foo1 = Column()
    bar1 = Column()
    cache_size = 5 
    #Some magic
    #Now I don't need to rewrite the search function with a different argument

有没有办法做到这一点?这是一种有效的使用方法吗?

这里是一种方法的示意图:

def deco(func):
    def newFunc(cls, *args, **kw):
        print "Decorated function using cache size", cls.cache_size
        return func(cls, *args, **kw)
    return newFunc

class Foo(object):
    cache_size = 10

    @classmethod
    @deco
    def meth(cls):
        print "Foo.meth()"

class Bar(Foo):
    cache_size = 20

>>> Foo.meth()
Decorated function using cache size 10
Foo.meth()
>>> Bar.meth()
Decorated function using cache size 20
Foo.meth()
我不知道你的备忘录装饰器到底做什么,所以这个例子只使用了一个虚拟装饰器。但是想法应该很清楚:编写decorator,以便它查看类的缓存大小,而不是将缓存大小作为参数传递

只是想澄清一点:在您的示例中,当您在
SearchMixin
上创建
search
方法并应用
@memoize(100)
时,“原始”搜索方法——即不带备忘录的未修饰版本——实际上已不存在。如果在decorator调用时缓存大小是固定的,那么您就不能返回内部,稍后仅仅通过分配一个类变量来更改它。最终,您需要以某种方式重构decorator,以便它从某些外部源(例如,类)检索所需的缓存大小


(如果你的备忘录装饰器实际上是一个类,那么可能会使它更聪明、更隐蔽,这样它就会注意到它是否在“重新装饰”已使用同一个装饰器包装的方法。在这种情况下,Memorization类可以修改其内部缓存大小变量,而不是添加另一层包装。但是,在不了解Memorizati的情况下,很难说这将如何工作,或者它将如何与其他装饰器交互这是一个简单的方法:

def deco(func):
    def newFunc(cls, *args, **kw):
        print "Decorated function using cache size", cls.cache_size
        return func(cls, *args, **kw)
    return newFunc

class Foo(object):
    cache_size = 10

    @classmethod
    @deco
    def meth(cls):
        print "Foo.meth()"

class Bar(Foo):
    cache_size = 20

>>> Foo.meth()
Decorated function using cache size 10
Foo.meth()
>>> Bar.meth()
Decorated function using cache size 20
Foo.meth()
我不知道你的备忘录装饰器到底做什么,所以这个例子只使用了一个虚拟装饰器。但是想法应该很清楚:编写decorator,以便它查看类的缓存大小,而不是将缓存大小作为参数传递

只是想澄清一点:在您的示例中,当您在
SearchMixin
上创建
search
方法并应用
@memoize(100)
时,“原始”搜索方法——即不带备忘录的未修饰版本——实际上已不存在。如果在decorator调用时缓存大小是固定的,那么您就不能返回内部,稍后仅仅通过分配一个类变量来更改它。最终,您需要以某种方式重构decorator,以便它从某些外部源(例如,类)检索所需的缓存大小


(如果你的备忘录装饰器实际上是一个类,那么可能会使它更聪明、更隐蔽,这样它就会注意到它是否在“重新装饰”已使用同一个装饰器包装的方法。在这种情况下,Memorization类可以修改其内部缓存大小变量,而不是添加另一层包装。但是,在不了解Memorizati的情况下,很难说这将如何工作,或者它将如何与其他装饰器交互这是一个简单的方法:

def deco(func):
    def newFunc(cls, *args, **kw):
        print "Decorated function using cache size", cls.cache_size
        return func(cls, *args, **kw)
    return newFunc

class Foo(object):
    cache_size = 10

    @classmethod
    @deco
    def meth(cls):
        print "Foo.meth()"

class Bar(Foo):
    cache_size = 20

>>> Foo.meth()
Decorated function using cache size 10
Foo.meth()
>>> Bar.meth()
Decorated function using cache size 20
Foo.meth()
我不知道你的备忘录装饰器到底做什么,所以这个例子只使用了一个虚拟装饰器。但是想法应该很清楚:编写decorator,以便它查看类的缓存大小,而不是将缓存大小作为参数传递

只是想澄清一点:在您的示例中,当您在
SearchMixin
上创建
search
方法并应用
@memoize(100)
时,“原始”搜索方法——即不带备忘录的未修饰版本——实际上已不存在。如果在decorator调用时缓存大小是固定的,那么您就不能返回内部,稍后仅仅通过分配一个类变量来更改它。最终,您需要以某种方式重构decorator,以便它从某些外部源(例如,类)检索所需的缓存大小


(如果你的备忘录装饰器实际上是一个类,那么可能会使它更聪明、更隐蔽,这样它就会注意到它是否在“重新装饰”已使用同一个装饰器包装的方法。在这种情况下,Memorization类可以修改其内部缓存大小变量,而不是添加另一层包装。但是,在不了解Memorizati的情况下,很难说这将如何工作,或者它将如何与其他装饰器交互这是一个简单的方法:

def deco(func):
    def newFunc(cls, *args, **kw):
        print "Decorated function using cache size", cls.cache_size
        return func(cls, *args, **kw)
    return newFunc

class Foo(object):
    cache_size = 10

    @classmethod
    @deco
    def meth(cls):
        print "Foo.meth()"

class Bar(Foo):
    cache_size = 20

>>> Foo.meth()
Decorated function using cache size 10
Foo.meth()
>>> Bar.meth()
Decorated function using cache size 20
Foo.meth()
我不知道你的备忘录装饰器到底做什么,所以这个例子只使用了一个虚拟装饰器。但是想法应该很清楚:编写decorator,以便它查看类的缓存大小,而不是将缓存大小作为参数传递

只是想澄清一点:在您的示例中,当您在
SearchMixin
上创建
search
方法并应用
@memoize(100)
时,“原始”搜索方法——即不带备忘录的未修饰版本——实际上已不存在。如果在decorator调用时缓存大小是固定的,那么您就不能返回内部,稍后仅仅通过分配一个类变量来更改它。最终,您需要以某种方式重构装饰