Python:特定于decorator的参数(与包装函数无关)?

Python:特定于decorator的参数(与包装函数无关)?,python,decorator,Python,Decorator,我希望构建一个缓存装饰器,给定一个函数,它将函数的结果缓存到装饰中指定的位置。大概是这样的: @cacheable('/path/to/cache/file') def my_function(a, b, c): return 'something' decorator的参数与它所包装的函数的参数完全分离。我已经看了很多例子,但是我不太明白怎么做-有可能有一个decorator的参数与包装函数无关并且没有传递给包装函数吗?这个想法是你的decorator是一个返回decorator的函

我希望构建一个缓存装饰器,给定一个函数,它将函数的结果缓存到装饰中指定的位置。大概是这样的:

@cacheable('/path/to/cache/file')
def my_function(a, b, c):
    return 'something'

decorator的参数与它所包装的函数的参数完全分离。我已经看了很多例子,但是我不太明白怎么做-有可能有一个decorator的参数与包装函数无关并且没有传递给包装函数吗?

这个想法是你的decorator是一个返回decorator的函数

首先编写装饰程序,就好像您知道您的参数是一个全局变量一样。比如说:

-

然后编写一个将cachepath作为参数的函数,并返回装饰器

-


是的。正如你所知,装饰是一种功能。在表格中填写时:

def mydecorator(func):
   def wrapper(*args, **kwargs):
       return func(*args, **kwargs)
   return wrapper

@mydecorator
def foo(a, b, c):
    pass
传递给
mydecorator
的参数是函数
foo
本身

当decorator接受一个参数时,调用
@mydecorator('/path/to')
实际上将首先使用'/path/to'调用mydecorator函数。然后,调用
mydecorator(path)
的结果将被调用以接收函数
foo
。您正在有效地定义一个动态包装器函数

简而言之,您需要另一层装饰器函数

下面是一个有点愚蠢的例子:

def addint(val):
    def decorator(func):
        def wrapped(*args, **kwargs):
            result = func(*args, **kwargs)
            return result + val
        return wrapped # returns the decorated function "add_together"
     return decorator # returns the definition of the decorator "addint"
                      # specifically built to return an extra 5 to the sum

@addint(5)
def add_together(a, b):
    return a + b

print add_together(1, 2)
# prints 8, not 3

Paul的回答很好,我会移动缓存对象,这样就不需要每次都构建它,并设计缓存,以便在缓存未命中时引发KeyError:

def cache(filepath): def decorator(f): f._cache = Cache(cachepath) def decorated(*args,**kwargs): try: key = (args, kwargs) res = f._cache.get(key) except KeyError: res = f(*args, **kwargs) f._cache.put(key, res) return res return decorated return decorator def缓存(文件路径): def装饰器(f): f、 _cache=cache(cachepath) def装饰(*args,**kwargs): 尝试: 键=(args,kwargs) res=f.\u cache.get(键) 除KeyError外: res=f(*args,**kwargs) f、 _cache.put(键,res) 返回res 回报 返回装饰器
def addint(val):
    def decorator(func):
        def wrapped(*args, **kwargs):
            result = func(*args, **kwargs)
            return result + val
        return wrapped # returns the decorated function "add_together"
     return decorator # returns the definition of the decorator "addint"
                      # specifically built to return an extra 5 to the sum

@addint(5)
def add_together(a, b):
    return a + b

print add_together(1, 2)
# prints 8, not 3
def cache(filepath): def decorator(f): f._cache = Cache(cachepath) def decorated(*args,**kwargs): try: key = (args, kwargs) res = f._cache.get(key) except KeyError: res = f(*args, **kwargs) f._cache.put(key, res) return res return decorated return decorator