2010-08-06 5 views
13

함수 내에서 정규 표현식을 컴파일하고 그 함수가 여러 번 호출되면 파이썬은 매번 정규식을 다시 컴파일합니까 아니면 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 

답변

11

실제로 re 모듈에서 코드를 보면 re.compile 함수는 다른 모든 함수와 마찬가지로 캐시를 사용합니다 그렇기 때문에 동일한 정규 표현식을 반복해서 컴파일하는 것은 매우 저렴합니다 (사전 조회). 즉, 가장 이해하기 쉽거나 유지 보수가 가능하거나 표현 적이도록 코드를 작성하고 정규 표현식을 컴파일하는 오버 헤드에 대해 걱정하지 마십시오.

+0

맞습니다. [_.pypile function in re.py] (https://github.com/python/cpython/blob/master/Lib/re.py#L278)를 참조하십시오. – pevik

0

그것은 "잘못된"일이 여기에 주제에 더 이상 스레드의 않습니다. 당신이) (마다 re.compile를 호출의 오버 헤드를 피하기 위해 원하는 경우

I'm using Python regexes in a criminally inefficient manner

+1

사실 링크는 캐시가 올바른지를 알려주지 만 캐시를 확인하는 데 속도가 떨어집니다. – katrielalex

6

, 당신은 할 수 있습니다 :

def contains_text_of_interest(line, r = re.compile(r"foo\dbar\d")): 
    return r.match(line) 
+4

+1 내 말은, 파이썬의 기본 인자 처리가 유용하다고 생각하지 않는다. – katrielalex

2

왜 그냥 re.compile 외부 기능을 넣지 마십시오 (모듈 또는 클래스 수준에서) 명시 적 이름을 지정하고 사용하면됩니까? 그 종류의 정규식은 일종의 정규식이며 당신은 그것을 같은 방식으로 다룰 수 있습니다.

MATCH_FOO_BAR = re.compile(r"foo\dbar\d") 

def contains_text_of_interest(line): 
    return MATCH_FOO_BAR.match(line) 
+3

이것은 내가 지금까지 해왔 던 것이지만, 이것은 제가 사용하고자하는 것보다 더 멀리 정규식을 정의하도록 강요합니다. –

2

딩고의 솔루션은 좋은 하나입니다 [편집 : 네드 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가 한 번만 호출되기 때문에 정규식은 한 번만 컴파일 : 개념은 간단하다. contains_text_of_interest에 할당 된 함수 f은 주변 범위에 있기 때문에 컴파일 된 정규식 matcher을 알고 있으며 contains_text_of_interest을 다른 곳에서도 사용한다고해도 그 사실을 항상 알 수 있습니다 (클로저 : 코드로 둘러싸인 코드) .

이 문제에 대한 대부분의 Pythonic 솔루션은 아닙니다. 하지만 시간이 맞을 때 슬리브를 사용하는 것은 좋은 숙달입니다.