我发现自己经常编写这样的代码:
_munge_text_re = re.compile("... complicated regex ...")
def munge_text(text):
match = _munge_text_re.match(text)
... do stuff with match ...只有munge_text使用_munge_text_re,所以最好以某种方式将其定位到函数中,但是如果我将re.compile行移动到def中,那么每次调用该函数时都会对其进行评估,这就违背了编译正则表达式的目的。
是否有一种方法可以使_munge_text_re本地到munge_text,同时仍然只计算它的初始化项一次?单个评估不需要在模块加载时进行;在第一次调用munge_text时就足够了。
这个例子使用regex,在我需要它的大多数时候,它是用于regex的,但是它可能是任何数据块,实例化(所以您不想每次调用函数时都这样做)并在程序的生存期内进行修复。ConfigParser实例也出现在脑海中。
额外的原因:我现在的项目需要极强的向后兼容性,所以在Python2.0中工作的解决方案要比没有的好。
发布于 2013-07-04 02:29:16
既然它已经有了状态,只需为它创建一个类:
class TextMunger(object):
def __init__(self, regex):
self._pattern = regex
self._munge_text_re = None
def __call__(self, text):
if self._munge_text_re is None:
self._munge_text_re = re.compile(self._pattern)
match = self._munge_text_re.match(text)
# ... do stuff with match ...
munge_text = TextMunger("... complicated regex ...")
# The rest of your code stays the same如果您不知道,类上的__call__方法意味着可以像调用函数一样调用对象,因此您可以像以前一样继续使用munge_text(text)。
(这类问题实际上导致了我关于Python中的lazy property decorator的问题,这也可能会让您感兴趣;但是,除非您发现自己经常重复这种模式,否则我不会为此烦恼。)
发布于 2013-07-04 02:28:29
_munge_text_re = None
def munge_text(text):
global _munge_text_re
_munge_text_re = _munge_text_re or re.compile("... complicated regex ...")
match = _munge_text_re.match(text)
... do stuff with match ...发布于 2013-07-04 02:59:07
另一种方法--我只提到这是为了获取信息,而不是因为我会在生产中使用它,所以我将社区-- wiki这个--是将状态存储在函数本身中。您可以使用hasattr,也可以捕获AttributeError
def munge1(x):
if not hasattr(munge1, 'val'):
print 'expensive calculation'
munge1.val = 10
return x + munge1.val
def munge2(x):
try:
munge2.val
except AttributeError:
print 'expensive calculation'
munge2.val = 10
return x + munge2.val之后
>>> munge1(3)
expensive calculation
13
>>> munge1(3)
13
>>> munge2(4)
expensive calculation
14
>>> munge2(4)
14但老实说,我通常在这一点上转到一堂课。
https://stackoverflow.com/questions/17460961
复制相似问题