Компиляция регулярного выражения внутри функции, вызывающей несколько раз
Если вы компилируете регулярное выражение внутри функции, и эта функция вызывается несколько раз, Python перекомпилирует регулярное выражение каждый раз, или Python кэширует скомпилированное регулярное выражение (при условии, что регулярное выражение не изменяется)?
Например:
def contains_text_of_interest(line):
r = re.compile(r"foo\dbar\d")
return r.match(line)
def parse_file(fname):
for line in open(fname):
if contains_text_of_interest(line):
# Do something interesting
Ответы
Ответ 1
Фактически, если вы посмотрите на код в модуле re, функция re.compile использует кеш так же, как и все остальные функции, поэтому скомпилировать одно и то же регулярное выражение снова и снова очень дешево (поиск в словаре), Другими словами, напишите код как наиболее понятный или удобный или выразительный, и не беспокойтесь о накладных расходах на компиляцию регулярных выражений.
Ответ 2
Если вы хотите избежать накладных расходов на вызов re.compile() каждый раз, вы можете сделать:
def contains_text_of_interest(line, r = re.compile(r"foo\dbar\d")):
return r.match(line)
Ответ 3
Почему бы вам просто не поместить внешние функции re.compile(на уровне модуля или класса), дать ему явное имя и просто использовать его? Такое регулярное выражение является своего рода константой, и вы можете относиться к нему одинаково.
MATCH_FOO_BAR = re.compile(r"foo\dbar\d")
def contains_text_of_interest(line):
return MATCH_FOO_BAR.match(line)
Ответ 4
Решение Dingo - это хороший вариант [редактировать: объяснение Ned Batchelder еще лучше], но вот еще один, который я считаю аккуратным: используйте закрытие! Если это звучит как "большое слово", не беспокойтесь. Концепция проста:
def make_matching_function():
matcher = re.compile(r"foo\dbar\d")
def f(line):
return matcher.match(line)
return f
contains_text_of_interest = make_matching_function()
make_matching_function
вызывается только один раз, поэтому регулярное выражение компилируется только один раз. Функция f
, которая присваивается contains_text_of_interest
, знает о скомпилированном регулярном выражении matcher
, потому что она находится в окружении и всегда будет знать об этом, даже если вы используете contains_text_of_interest
где-то еще (что замыкает: код который принимает окружающий объем с ним).
Не самое питоническое решение этой проблемы, конечно. Но это хорошая идиома, чтобы иметь дело с твоим рукавом, потому что, когда настало время:)
Ответ 5
Он делает "неправильную" вещь, здесь длинный поток темы.
Я использую регулярные выражения Python преступно неэффективно