Python装饰器,self混乱了

2024-05-29 11:21:32 发布

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

我是Python decorators的新手(哇,很棒的特性!),并且我很难让下面的操作生效,因为self参数有点混淆。

#this is the decorator
class cacher(object):

    def __init__(self, f):
        self.f = f
        self.cache = {}

    def __call__(self, *args):
        fname = self.f.__name__
        if (fname not in self.cache):
            self.cache[fname] = self.f(self,*args)
        else:
            print "using cache"
        return self.cache[fname]

class Session(p.Session):

    def __init__(self, user, passw):
        self.pl = p.Session(user, passw)

    @cacher
    def get_something(self):
        print "get_something called with self = %s "% self
        return self.pl.get_something()

s = Session(u,p)
s.get_something()

当我运行这个时,我得到:

get_something called with self = <__main__.cacher object at 0x020870F0> 
Traceback:
...
AttributeError: 'cacher' object has no attribute 'pl'

对于我所做的行self.cache[fname] = self.f(self,*args)

问题-显然,问题是self是缓存对象,而不是会话实例,它确实没有pl属性。但是我找不到解决这个问题的方法。

我考虑过的解决方案,但不能使用-我想让decorator类返回一个函数而不是一个值(如本article的第2.1节所述),以便在正确的上下文中计算self,但这是不可能的,因为我的decorator是作为类实现的,并且使用了内置的__call__方法。然后我想不使用一个类作为我的decorator,这样我就不需要调用方法了,但是我不能这样做,因为我需要在decorator调用之间保持状态(即跟踪self.cache属性中的内容)。

问题-那么,除了使用全局{}字典变量(我没有尝试,但假设它会工作)之外,还有其他方法可以使这个装饰器工作吗?

编辑:这个问题看起来很相似Decorating python class methods, how do I pass the instance to the decorator?


Tags: the方法selfcachegetobjectsessiondef

热门问题