[파이썬 파일 처리] 파일 존재 확인 및 특정 유형 필터링 핵심 해결 방법

파이썬 개발을 시작하는 분들이라면 파일 시스템과의 상호작용은 피할 수 없는 필수 과정입니다. 특히 런타임에 파일의 존재 여부를 확인하거나, 명령줄 인수로 전달된 수많은 파일 중 특정 유형(예: 파이썬 파일)만 선별하여 처리해야 할 때 초보 개발자들은 종종 어려움을 겪곤 합니다. 이 글에서는 이러한 일반적인 문제 상황을 명확히 분석하고, 실제 코드 예시와 함께 가장 효율적인 해결 방법을 제시합니다.

1. 문제 발생 상황

파이썬 프로젝트를 진행하면서 다음과 같은 시나리오에 직면할 수 있습니다.

1.1 런타임 시 파이썬 파일 존재 여부 확인 및 부재 시 처리

스크립트가 실행될 때 특정 설정 파일, 모듈 또는 데이터 파일이 존재하는지 확인해야 할 때가 있습니다. 만약 파일이 존재하지 않는다면, 프로그램이 비정상적으로 종료되는 대신 사용자에게 알리거나 기본값을 로드하는 등 적절한 방식으로 대응해야 합니다. 예를 들어, 사용자가 특정 스크립트를 실행했는데, 해당 스크립트가 의존하는 모듈 파일이 없어서 오류가 발생하는 경우를 들 수 있습니다.

1.2 명령줄 인수 중 파이썬 파일만 선별하여 처리

개발자는 종종 명령줄을 통해 여러 파일 경로를 프로그램에 인수로 전달합니다. 이때, 주어진 파일 목록 중 파이썬 스크립트(.py) 파일만 골라내어 특정 로직(예: 코드 분석, 실행 등)을 적용하고 싶을 수 있습니다. 예를 들어, 프로젝트 디렉토리의 모든 파일 중 파이썬 파일만을 대상으로 코드 포맷팅 도구를 실행해야 하는 상황이 여기에 해당합니다.

2. 명확한 문제 원인

위에서 언급된 상황들은 “에러”라기보다는 파이썬 스크립트를 견고하고 유연하게 만들기 위해 반드시 알아야 할 “파일 시스템 상호작용 및 명령줄 인수 처리” 기술에 대한 질문입니다. 문제의 본질은 다음과 같습니다.

2.1 파일 존재 확인 미숙

파이썬 표준 라이브러리에서 파일 또는 디렉토리의 존재 여부를 확인하는 기능을 알지 못하거나, 이를 활용하여 예외를 처리하는 방법에 대한 이해가 부족할 때 발생합니다. 파일이 없는데 강제로 열려고 하면 FileNotFoundError와 같은 예외가 발생하여 프로그램이 크래시될 수 있습니다.

2.2 명령줄 인수 처리 및 파일 유형 필터링 미숙

파이썬 스크립트가 명령줄 인수를 어떻게 받는지(sys.argv), 그리고 이 인수들이 문자열로 주어졌을 때 특정 패턴(파일 확장자)을 기반으로 필터링하는 방법에 대한 지식이 부족할 때 발생합니다.

3. 해결 방법 및 코드 예시

이제 각 문제에 대한 구체적인 해결 방법과 함께 실용적인 파이썬 코드 예시를 살펴보겠습니다.

3.1 파일 존재 여부 확인 및 처리

파이썬에서는 os.path 모듈이나 pathlib 모듈을 사용하여 파일의 존재 여부를 확인할 수 있습니다. 파일을 열 때 발생할 수 있는 FileNotFoundError를 try-except 블록으로 처리하는 것이 가장 견고한 방법입니다.

os.path.exists() 사용

가장 간단한 방법으로, 파일 또는 디렉토리가 존재하는지 여부를 불리언 값으로 반환합니다.

import os

file_name = "my_script.py"

if os.path.exists(file_name):
    print(f"'{file_name}' 파일이 존재합니다.")
    # 파일 처리 로직
    with open(file_name, 'r', encoding='utf-8') as f:
        content = f.read()
        print(f"파일 내용 일부: {content[:50]}...")
else:
    print(f"경고: '{file_name}' 파일을 찾을 수 없습니다.")
    # 파일이 없을 때의 대체 로직 또는 종료
    # sys.exit(1) 와 같이 프로그램 종료 가능

pathlib.Path.is_file() 사용 (권장)

pathlib 모듈은 객체 지향적인 방식으로 경로를 다룰 수 있게 하여, 더욱 직관적이고 견고한 코드 작성을 돕습니다. is_file() 메서드는 해당 경로가 일반 파일인지 확인합니다.

from pathlib import Path

file_path = Path("another_script.py")

if file_path.is_file():
    print(f"'{file_path}' 파일이 존재합니다.")
    # 파일 처리 로직
    with file_path.open('r', encoding='utf-8') as f:
        content = f.read()
        print(f"파일 내용 일부: {content[:50]}...")
else:
    print(f"경고: '{file_path}' 파일을 찾을 수 없습니다.")
    # 파일이 없을 때의 대체 로직

try-except를 사용한 파일 열기 시 예외 처리

파일을 열려고 시도했을 때 FileNotFoundError 예외를 처리하는 방법은 파일 존재 확인과 동시에 파일 사용 로직을 포함할 수 있어 매우 강력합니다.

try:
    with open("non_existent_file.txt", 'r', encoding='utf-8') as f:
        content = f.read()
        print(f"파일 내용: {content}")
except FileNotFoundError:
    print("오류: 파일을 찾을 수 없습니다. 기본값을 로드합니다.")
    # 파일이 없을 때의 대체 로직 (예: 기본 설정 로드)
except Exception as e:
    print(f"예기치 않은 오류 발생: {e}")
finally:
    print("파일 처리 시도 완료.")

3.2 명령줄 인수로 전달된 파일 중 파이썬 파일만 필터링

파이썬 스크립트는 sys 모듈의 argv 리스트를 통해 명령줄 인수를 전달받습니다. 이 리스트에서 파이썬 파일(.py)만 골라낼 수 있습니다.

import sys
from pathlib import Path

# 예시 실행: python your_script.py script1.py data.txt utility.py config.ini

# sys.argv[0]은 스크립트 자체의 이름이므로, 첫 번째 인수는 sys.argv[1]부터 시작합니다.
command_line_args = sys.argv[1:] 

python_files = []
ignored_files = []

for arg in command_line_args:
    # pathlib.Path 객체를 사용하여 파일 확장자 확인
    path_obj = Path(arg)
    
    if path_obj.suffix == '.py' and path_obj.is_file():
        python_files.append(arg)
    else:
        ignored_files.append(arg)

print("--- 처리할 파이썬 파일 ---")
if python_files:
    for f in python_files:
        print(f"- {f}")
        # 여기에 각 파이썬 파일에 대한 처리 로직 추가 (예: 실행, 분석)
else:
    print("처리할 파이썬 파일이 없습니다.")

print("\n--- 무시된 파일 (파이썬 파일 아님 또는 존재하지 않음) ---")
if ignored_files:
    for f in ignored_files:
        print(f"- {f}")
else:
    print("무시된 파일이 없습니다.")

# 리스트 컴프리헨션을 사용하면 더 간결합니다.
# python_files_compact = [arg for arg in command_line_args if Path(arg).suffix == '.py' and Path(arg).is_file()]
# print(f"\n간결한 방식: {python_files_compact}")

위 코드 예시는 명령줄 인수로 받은 파일 경로를 pathlib.Path 객체로 변환한 후, suffix 속성을 이용해 확장자가 ‘.py’인지 확인하고 is_file()로 실제 파일인지 한 번 더 검증하여 견고함을 높였습니다.

4. 향후 예방을 위한 팁

개발자는 항상 파일 처리 로직에 대해 다음과 같은 모범 사례를 따르는 것이 좋습니다.

  • 철저한 유효성 검사: 파일 경로를 사용자로부터 받거나 다른 시스템에서 가져올 때는 항상 해당 경로가 유효한지, 파일이 존재하는지, 그리고 접근 권한이 있는지 등을 확인해야 합니다.
  • 적절한 예외 처리: 파일 관련 작업은 예기치 않은 오류(파일 없음, 권한 문제, 디스크 가득 참 등)가 발생하기 쉽습니다. try-except 블록을 적극적으로 사용하여 프로그램의 안정성을 높이세요.
  • pathlib 모듈 활용: os.path보다 현대적이고 객체 지향적인 pathlib 모듈을 사용하면 경로 조작이 훨씬 직관적이고 안전해집니다. 파일 유형, 이름, 확장자 등을 쉽게 다룰 수 있습니다.
  • argparse 모듈 학습: 복잡한 명령줄 인수를 처리해야 할 경우, argparse 모듈을 사용하면 인수의 파싱, 유효성 검사, 도움말 메시지 생성 등을 훨씬 쉽게 관리할 수 있습니다. 이는 사용자 경험을 크게 향상시킵니다.
  • 단위 테스트(Unit Test) 작성: 파일 처리 로직이 중요한 부분이라면, 단위 테스트를 작성하여 다양한 시나리오(파일 존재, 파일 부재, 빈 파일, 권한 없음 등)에서 코드가 예상대로 동작하는지 검증하세요.

이러한 팁들을 통해 여러분의 파이썬 스크립트가 더욱 견고하고 사용자 친화적으로 발전할 수 있을 것입니다.

댓글 남기기