2015-01-31 3 views
1

대용량 파일을 실행하면서 구문 분석을 수행하는이 스크립트를 작성했습니다. 파일의 모든 행에 대해 (무거운 조작을 한 후), 특정 기준을 충족하는지 확인하기 위해 점검을 추가해야하며, 추가 기준을 충족하는지 여부를 나중에 추가 처리 목록에 포함 시키십시오.Python 함수의 영구 변수

파싱을 수행하는 함수는 이미 약간 복잡해졌으며 나중에 라인 수정 및 목록 조작을 다른 함수로 변경하여 나중에 쉽게 수정할 수 있는지 궁금합니다. 내 성향은 함수에 의해 수정 된 전역 변수를 사용하는 것이지만, 일반적으로 빈약 한 형태라는 것을 알고 있습니다. 지금까지 클래스를 사용한 적이 한번도 없었지만 영구적 인 지역 변수에 관해서는 이점이 있다는 것을 모호하게 기억합니다. 스크립트의이 부분의

한 버전이 될 수있다 :

matchingLines = [] 
def lineProcess(line): 
    global matchingLines 
    if line.startswith(criteria): 
     matchingLines.append(line) 
for line in myFile: 
    # lots of other stuff 
    lineProcess(line) 

은 분명히이 간단한 예제에서 단지 주요 기능에 체크를하고 추가 기능을 방해하지 않는 고통의 많은 부분이 아니다. 그러나 원칙적으로, 나는 이런 종류의 일을하는 더 나은 일반적인 방법이 외부 변수를 사용하지 않고 무엇인지 궁금합니다.

EDIT : 필자가 별도의 기능을 매력적으로 느낀 이유 중 하나는 선 목록을 수집했기 때문에 다른 외부 파일을 조작하기 위해이를 사용할 것이므로 전체 운영을 감싸는 것이 편리 할 것이기 때문입니다 포함 된 모듈에서. 그러나 이것은 조숙 한 최적화라고 생각합니다.

답변

3

: 덧붙여

def is_valid_line(line): 
    """Return True if the line is valid, else False.""" 
    return line.startswith(criteria) 

valid_lines = [l for l in myFile if is_valid_line(l)] 

예를 들어, 목록이 아닌 발전기 표현을 사용하는 더 좋은 연습이 될 것이다

valid_lines = (l for l in myFile if is_valid_line(l)) 

그런 식으로 파일 읽기 및 줄 확인은 실제로 무언가가 valid_lines를 통해 반복 할 때만 발생하며 이전에는 시도하지 않습니다. 예 : 다음과 같은 경우 :이 경우

valid_lines = [l for l in myFile if is_valid_line(l)] 
for line in valid lines: 
    stuff_that_can_raise_exception(line) 

, 읽고 전체 (큰) 파일을 확인 및 검증 라인의 전체 목록을 한 다음 첫 번째 줄에 오류가 발생 한 시간은 유효성을 검사하는 동안 전체 파일이 낭비됩니다. 목록 이해 ([x for x in y]) 대신 발전기 표현식 ((x for x in y)) 버전을 사용하면 오류가 발생해도 실제로 파일을 검증하지 않았습니다 (첫 번째 행만). 나는 더 자주이 일을하지 않는 것이 끔찍하기 때문에 언급 만한다. 많은 경우 CPU와 메모리에서 큰 성능 향상을 가져올 수있다.

+0

확실히. 내가 Eevee에 대한 응답으로 썼을 때, 아마 나는 철학적 질문을하고있다. 나는 복잡성에 잘 비례하는 시스템을 갖고 싶다. 그리고 관련된 기준에 따라 나는 이런 종류의 해결책이 나를 지금까지만 받아 들일 것으로 생각한다. – glarue

+0

File을 하위 클래스로하는 클래스로 별도의 모듈을 만들고 해당 클래스가 일치하지 않는 모든 행을 효과적으로 숨길 수 있습니다.하지만 글로벌 변수와 관련이 있는지 확신 할 수 없습니다. 왜 당신이 전혀 필요하지 않을지 생각하는 이유는 아직 명확하지 않습니다. 시스템이 어떻게 복잡해질 필요가 있는지 예를들 수 있다면 아키텍처 나 디자인 패턴이 도움이 될 수있는 몇 가지 팁을 제공 할 수 있습니다. –

+0

예, 질문하지 않기 전에 질문하기 전의 증후군을 앓고있는 것 같습니다. 위의 모든 것이 함수 내에서 일어나기 때문에 전역 변수가 작동합니다. 일치하는 목록으로 수행해야하는 파일 처리는 여기에서 상위 함수 외부에서 발생합니다. 물론이 부모 함수가 일치하는 목록을 반환하도록 할 수는 있지만 다른 많은 내용을 다시 작성해야합니다. 그게 전혀 도움이 되나요? – glarue

1

클래스를 사용하고 matching_lines을 특성으로 사용할 수 있습니다. 그러나 당신은 또한 바로이 작업을 수행 할 수 있습니다 :

다음과 같은 뭔가 더 파이썬 간주 될 수
def process_line(line, matching_lines): 
    if line.startswith(criteria): 
     matching_lines.append(line) 

... 

matches = [] 
for line in my_file: 
    # lots of other stuff 
    process_line(line, matches) 
+0

응답 해 주셔서 감사합니다. 아마도 좀 더 공식적인 예를 들어야 할 것이지만, 일반적으로 이런 종류의 일을하는 가장 좋은 방법은 무엇인지 묻고있는 것 같습니다. 점점 더 복잡한 구문 분석 작업 (예 : 간단한 startswith() 확인이 아닌)을 수용하는 것입니다. 또는 무엇이든) 전역을 과용하지 않고 – glarue