装饰器中的全局变量

时间:2016-03-03 01:41:58

标签: python

我有一个名为profiled的装饰器,用于跟踪调用函数的次数。

class profiled(object):
    def __init__(self,f):
        self.__count=0
        self.__f=f
        self.__name__=f.__name__
    def __call__(self,*args,**dargs):
        self.__count+=1
        return self.__f(*args,**dargs)
    def count(self):
        return self.__count
    def reset(self):
        self.__count=0

如何将count变量设置为全局,以便当我使用具有可变函数的profiled时,将存储总计数而不是仅具有特定函数的计数。

1 个答案:

答案 0 :(得分:0)

您需要使用类属性,并且您需要确保永远不会直接在self上分配它(这将创建一个影响类属性的实例属性)。您可以通过更改:

来完成此操作
class profiled(object):
    def __init__(self,f):
        self.__count=0
        self.__f=f
        self.__name__=f.__name__
    def __call__(self,*args,**dargs):
        self.__count+=1
        return self.__f(*args,**dargs)
    def reset(self):
        self.__count=0

to(对行内变化的评论):

class profiled(object):
    __count=0  # Class attribute shared for all @profiled functions
    def __init__(self,f):
        self.__f=f
        self.__name__=f.__name__
    def __call__(self,*args,**dargs):
        type(self).__count+=1  # Increment __count on the type, not the instance
        return self.__f(*args,**dargs)

    # Use a classmethod here, since we don't need self at all
    @classmethod
    def reset(cls):
        cls.__count=0

count方法不需要更改(尽管您也可以将其设为@classmethod,因为不涉及特定于实例的内容),因为即使作为实例方法,它也只是读取__count,而不是编写它,它不会创建实例属性来隐藏类属性,并无缝地访问类属性。