更改子类中的装饰器参数

2024-06-02 16:53:45 发布

您现在位置:Python中文网/ 问答频道 /正文

不确定这是不是一个恰当的问题,但问题是。你知道吗

我有一个memoized decorator(实现为类)。decorator接受的参数是缓存的大小。我希望我的DB模型类每个都有一个搜索方法,所以我编写了一个mixin(我认为它是一个mixin)

class SearchMixin(object): 
    @classmethod
    @memoized(100)
    def search(cls,session,**kwargs): 
        q = session.query(cls)
        for k,v in kwargs.items(): 
            q = q.filter(getattr(cls,k,None).__eq__(v))
        res = q.one()
        return res

在我的模型里

class ModelA(Base,SearchMixin): 
    foo = Column()
    bar = Column() 
    #And so on

现在我可以做一个ModelA.search(foo=x,bar=y),如果以前请求过相同的查询,memoized decorator就会工作并从缓存返回。你知道吗

问题是,对于某些模型,我需要更改某些搜索的缓存大小(这是通过在SearchMixin中定义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

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


Tags: 模型searchbase参数sessiondefcolumndecorator
1条回答
网友
1楼 · 发布于 2024-06-02 16:53:45

下面是一个方法的草图:

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,以便它从某些外部源(例如,类)检索所需的缓存大小。你知道吗

(如果您的memoization decorator实际上是一个类,那么可能会使它更智能、更隐蔽,这样它就会注意到是否正在“重新装饰”一个已经用同一个decorator包装的方法。在这种情况下,memoization类可以修改其内部缓存大小变量,而不是添加另一层包装。但是,如果不了解memoization decorator当前的操作方式,就很难准确地说出它将如何工作,或者它将如何与其他decorator交互。)

相关问题 更多 >