Python class decorator arguments

前端 未结 4 1696
走了就别回头了
走了就别回头了 2020-12-24 14:50

I\'m trying to pass optional arguments to my class decorator in python. Below the code I currently have:

class Cache(object):
    def __init__(self, function         


        
4条回答
  •  天涯浪人
    2020-12-24 15:29

    @Cache
    def double(...): 
       ...
    

    is equivalent to

    def double(...):
       ...
    double=Cache(double)
    

    While

    @Cache(max_hits=100, timeout=50)
    def double(...):
       ...
    

    is equivalent to

    def double(...):
        ...
    double = Cache(max_hits=100, timeout=50)(double)
    

    Cache(max_hits=100, timeout=50)(double) has very different semantics than Cache(double).

    It's unwise to try to make Cache handle both use cases.

    You could instead use a decorator factory that can take optional max_hits and timeout arguments, and returns a decorator:

    class Cache(object):
        def __init__(self, function, max_hits=10, timeout=5):
            self.function = function
            self.max_hits = max_hits
            self.timeout = timeout
            self.cache = {}
    
        def __call__(self, *args):
            # Here the code returning the correct thing.
    
    def cache_hits(max_hits=10, timeout=5):
        def _cache(function):
            return Cache(function,max_hits,timeout)
        return _cache
    
    @cache_hits()
    def double(x):
        return x * 2
    
    @cache_hits(max_hits=100, timeout=50)
    def double(x):
        return x * 2
    

    PS. If the class Cache has no other methods besides __init__ and __call__, you can probably move all the code inside the _cache function and eliminate Cache altogether.

提交回复
热议问题