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, 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.
@Cache
def double(x):
return x * 2
@Cache(max_hits=100, timeout=50)
def double(x):
return x * 2
The second decorator with arguments to overwrite the default one (max_hits=10, timeout=5
in my __init__
function), is not working and I got the exception TypeError: __init__() takes at least 2 arguments (3 given)
. I tried many solutions and read articles about it, but here I still can't make it work.
Any idea to resolve this? Thanks!
@Cache(max_hits=100, timeout=50)
calls __init__(max_hits=100, timeout=50)
, so you aren't satisfying the function
argument.
You could implement your decorator via a wrapper method that detected whether a function was present. If it finds a function, it can return the Cache object. Otherwise, it can return a wrapper function that will be used as the 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.
# wrap _Cache to allow for deferred calling
def Cache(function=None, max_hits=10, timeout=5):
if function:
return _Cache(function)
else:
def wrapper(function):
return _Cache(function, max_hits, timeout)
return wrapper
@Cache
def double(x):
return x * 2
@Cache(max_hits=100, timeout=50)
def double(x):
return x * 2