我正在尝试创建一个函数来缓存它的一些属性,因为这些函数需要一些计算才能返回结果。由于它是相同的结果,我想以某种方式缓存它,允许重用。
一些代码可以透视:
这就是我提出的装饰器的样子:
def cachedAttributes(func, **kwargs):
func.__dict__.update(kwargs)
return func
我想要装饰的类方法:
class someclass:
@staticmethod
def method(*args):
# compile regex operation
# compile regex operation
# compile regex operation
# compute and return something
...
pass
这就是我使用装饰器的方式
class someclass:
@staticmethod
@cachedAttributes(method, doctyperegex = re.compile(r'<!DOCTYPE.*?>\s*', re.S|re.U),
htmlregex = re.compile(r'<html.*?>\s*', re.S|re.U),
metaregex = re.compile(r'<meta(.*?)>', re.S|re.U))
def method(*args):
# compile regex operation
# compile regex operation
# compile regex operation
# compute and return something
...
pass
所以上面是我正在使用的代表。我有一个类,它有一个静态方法,使用一些正则表达式对象进行一些计算,我想缓存compile regex
操作的结果。但是,这给了我以下错误:
@staticmethod
NameError: name 'method' is not defined
我知道这是因为在尝试装饰之前没有定义方法,但我怎么能这样做呢?是否有内置可以为我做这个?
答案 0 :(得分:1)
您需要遵循以下常见模式:您需要一个获取预期参数并返回装饰器函数的函数。
def cachedAttributes(**kwargs):
def decorator(func):
func.__dict__.update(kwargs)
return func
return decorator
然后:
class someclass:
@staticmethod
@cachedAttributes(doctyperegex = re.compile(r'<!DOCTYPE.*?>\s*', re.S|re.U),
htmlregex = re.compile(r'<html.*?>\s*', re.S|re.U),
metaregex = re.compile(r'<meta(.*?)>', re.S|re.U))
def method(*args):
# compile regex operation
# compile regex operation
# compile regex operation
# compute and return something
...
pass
答案 1 :(得分:1)
当Python应用装饰器时,你的装饰器将被传递method
函数。你不需要给你的装饰工厂提供方法作为参数:
@cachedAttributes(doctyperegex = re.compile(r'<!DOCTYPE.*?>\s*', re.S|re.U),
htmlregex = re.compile(r'<html.*?>\s*', re.S|re.U),
metaregex = re.compile(r'<meta(.*?)>', re.S|re.U))
你的cachedAttributes()
callable然后返回实际的装饰器:
def cachedAttributes(**kwargs):
def decorator(func):
func.__dict__.update(kwargs)
return func
return decorator
所以Python调用cachedAttributes()
,它返回一个装饰器。然后调用传入函数对象,返回值用作装饰函数的替换。这可能是原始的功能对象,就像你在这里一样。