python
빠르게 Python 디렉토리 탐색: 모든 파일 쉽게 나열하기

빠르게 Python 디렉토리 탐색: 모든 파일 쉽게 나열하기

MoeNagy Dev

Python 디렉토리의 모든 파일 나열하기

현재 작업 디렉토리 가져오기

현재 작업 디렉토리 이해하기

현재 작업 디렉토리는 Python 스크립트가 현재 실행 중인 디렉토리입니다. 이것은 스크립트가 파일과 디렉토리를 찾을 기본 위치이며, 다른 경로를 명시적으로 지정하지 않는 한 새 파일을 생성하는 위치입니다.

os 모듈을 사용하여 현재 작업 디렉토리 확인하기

Python에서 현재 작업 디렉토리를 얻으려면 os.getcwd() 함수를 사용할 수 있습니다.

import os
 
current_dir = os.getcwd()
print(f"현재 작업 디렉토리는: {current_dir}")

이는 시스템에서 현재 작업 디렉토리의 전체 경로를 출력합니다.

디렉토리의 모든 파일 나열하기

os.listdir() 함수 사용하기

현재 작업 디렉토리의 모든 파일과 디렉토리 목록을 얻으려면 os.listdir() 함수를 사용할 수 있습니다.

import os
 
files_and_dirs = os.listdir()
print(f"현재 디렉토리의 내용: {files_and_dirs}")

이를 통해 현재 작업 디렉토리의 모든 항목 (파일과 디렉토리)의 목록이 반환됩니다.

빈 디렉토리 처리하기

현재 작업 디렉토리가 비어있는 경우, os.listdir()는 빈 목록을 반환합니다. 이러한 상태를 확인하고 그에 맞게 처리할 수 있습니다.

import os
 
files_and_dirs = os.listdir()
if not files_and_dirs:
    print("현재 디렉토리는 비어 있습니다.")
else:
    print(f"현재 디렉토리의 내용: {files_and_dirs}")

파일 목록 정렬하기

파일 목록을 정렬하려면 sorted() 함수를 사용할 수 있습니다.

import os
 
files_and_dirs = sorted(os.listdir())
print(f"현재 디렉토리의 정렬된 내용: {files_and_dirs}")

이를 통해 파일과 디렉토리의 목록이 알파벳순으로 반환됩니다.

하위 디렉토리 처리하기

하위 디렉토리 재귀적으로 탐색하기

하위 디렉토리를 포함하여 파일과 디렉토리의 목록을 모두 나열하려면 재귀적인 접근 방식을 사용할 수 있습니다. 이 방법은 각 하위 디렉토리마다 os.listdir() 함수를 호출하고 전체 파일 목록을 구성하는 것을 포함합니다.

import os
 
def list_all_files(directory):
    """
    디렉토리와 하위 디렉토리를 재귀적으로 탐색하여 모든 파일의 목록을 반환합니다.
    """
    file_list = []
    for item in os.listdir(directory):
        item_path = os.path.join(directory, item)
        if os.path.isfile(item_path):
            file_list.append(item_path)
        elif os.path.isdir(item_path):
            file_list.extend(list_all_files(item_path))
    return file_list
 
# 사용 예제
all_files = list_all_files(os.getcwd())
print(f"디렉토리와 하위 디렉토리의 모든 파일: {all_files}")

list_all_files() 함수는 디렉토리 경로를 입력으로 받아 해당 디렉토리와 하위 디렉토리의 모든 파일의 목록을 반환합니다.

파일과 디렉토리 구분하기

os.path.isfile()os.path.isdir() 함수를 사용하여 디렉토리 목록의 항목이 파일인지 디렉토리인지 여부를 확인할 수 있습니다.

import os
 
for item in os.listdir(os.getcwd()):
    item_path = os.path.join(os.getcwd(), item)
    if os.path.isfile(item_path):
        print(f"{item}는 파일입니다.")
    elif os.path.isdir(item_path):
        print(f"{item}는 디렉토리입니다.")
    else:
        print(f"{item}는 알 수 없는 유형입니다.")

이 코드는 현재 디렉토리의 내용을 순회하며 각 항목이 파일인지, 디렉토리인지 또는 알 수 없는 유형인지 출력합니다.

숨겨진 파일과 디렉토리 처리하기

기본적으로 os.listdir()는 숨겨진 파일과 디렉토리 (점으로 시작하는 파일 및 디렉토리)를 포함합니다. 이를 제외하려면 이를 필터링할 수 있습니다.

import os
 
all_items = os.listdir(os.getcwd())
visible_items = [item for item in all_items if not item.startswith(".")]
print(f"표시 가능한 파일과 디렉토리: {visible_items}")

이를 통해 .hidden_file.txt 또는 .hidden_directory/와 같이 점으로 시작하는 숨겨진 파일과 디렉토리를 제외한 새로운 목록 visible_items를 생성할 수 있습니다.

파일 경로 다루기

전체 파일 경로 구성하기

디렉토리 내의 파일 작업을 할 때 종종 디렉토리와 파일 이름을 포함한 전체 파일 경로가 필요합니다. 전체 경로를 구성하기 위해 os.path.join() 함수를 사용할 수 있습니다.

import os
 
directory = os.getcwd()
filename = "example.txt"
full_path = os.path.join(directory, filename)
print(f"전체 파일 경로는: {full_path}")

이를 통해 현재 작업 디렉토리와 파일 이름을 포함한 전체 파일 경로가 출력됩니다.

디렉토리와 파일 이름 결합하기

os.path.join() 함수를 사용하여 디렉토리 이름과 파일 이름과 같은 여러 경로 구성 요소를 결합하는 데도 사용할 수 있습니다.

import os
 
directory1 = "documents"
directory2 = "reports"
filename = "report.pdf"
full_path = os.path.join(directory1, directory2, filename)
print(f"전체 파일 경로는: {full_path}")

이를 통해 "documents/reports/report.pdf" 경로가 생성됩니다.

파일 경로 정규화하기

가끔 파일 경로에는 불필요하거나 중복된 요소가 포함될 수 있습니다. 예를 들어 . (현재 디렉토리) 또는 .. (상위 디렉토리)와 같은 요소가 포함될 수 있습니다. 이러한 요소를 제거하려면 os.path.normpath() 함수를 사용할 수 있습니다.

import os
 
messy_path = "documents/./reports/../images/image.jpg"
normalized_path = os.path.normpath(messy_path)
print(f"정규화된 경로는: {normalized_path}")

이를 통해 documents/./reports/../images/image.jpg와 같은 난잡한 경로에서 요소가 제거된 정규화된 경로가 출력됩니다. 이 markdown 파일은 "documents/images/image.jpg"를 출력하는데, 불필요한 ... 요소는 제외됩니다.

파일 목록 필터링

파일 확장자에 따라 파일 선택하기

특정 파일 확장자를 가진 파일만 포함하는 파일 목록으로 필터링하려면, 리스트 내포(list comprehension)를 사용할 수 있습니다:

import os
 
all_files = os.listdir(os.getcwd())
txt_files = [file for file in all_files if file.endswith(".txt")]
print(f"현재 디렉토리의 텍스트 파일들: {txt_files}")

이렇게 하면 .txt 확장자를 가진 파일만 포함하는 txt_files라는 새로운 리스트가 생성됩니다.

특정 파일 또는 디렉토리 제외하기

리스트에서 특정 파일 또는 디렉토리를 제외할 수도 있습니다. 예를 들어, 점(.)으로 시작하는 파일이나 디렉토리(숨겨진 항목)를 제외하려면 다음과 같이 할 수 있습니다:

import os
 
all_items = os.listdir(os.getcwd())
visible_items = [item for item in all_items if not item.startswith(".")]
print(f"보이는 파일 및 디렉토리: {visible_items}")

고급 필터링을 위해 정규 표현식 사용하기

더 복잡한 필터링 요구 사항에는 정규 표현식을 사용할 수도 있습니다. Python의 re 모듈은 문자열에서 패턴을 일치시키는 강력한 방법을 제공합니다. 다음은 파일 목록을 필터링하는 데 정규 표현식을 사용하는 예입니다:

import os
import re
 
all_files = os.listdir(os.getcwd())
pattern = r"^report_\d{4}.txt$"
matching_files = [file for file in all_files if re.match(pattern, file)]
print(f"패턴과 일치하는 파일들: {matching_files}")

이렇게 하면 "^report_\d{4}.txt$"라는 정규 표현식 패턴과 일치하는 파일의 목록인 matching_files가 생성됩니다. 이 패턴은 "report_"로 시작하고 네 자리 숫자로 끝나는 ".txt"로 끝나는 파일을 찾습니다.

파일 정보 출력하기

파일 크기, 생성/수정 일자 가져오기

os.path.getsize()os.path.getmtime() 함수를 사용하여 파일의 크기와 수정 시간을 가져올 수 있습니다:

import os
from datetime import datetime
 
file_path = os.path.join(os.getcwd(), "example.txt")
file_size = os.path.getsize(file_path)
modification_time = os.path.getmtime(file_path)
print(f"파일 크기: {file_size} 바이트")
print(f"마지막 수정일: {datetime.fromtimestamp(modification_time)}")

이렇게 하면 파일 크기와 "example.txt" 파일의 마지막 수정 시간이 출력됩니다.

포맷에 맞게 파일 세부 정보 출력하기

더 구성된 형식으로 파일 세부 정보를 인쇄하는 함수를 만들 수 있습니다:

import os
from datetime import datetime
 
def print_file_info(file_path):
    """
    파일 이름, 크기 및 수정 시간을 포함한 파일에 대한 자세한 정보를 출력합니다.
    """
    file_name = os.path.basename(file_path)
    file_size = os.path.getsize(file_path)
    modification_time = os.path.getmtime(file_path)
    print(f"파일 이름: {file_name}")
    print(f"파일 크기: {file_size} 바이트")
    print(f"마지막 수정일: {datetime.fromtimestamp(modification_time)}")
 
# 사용 예시
print_file_info(os.path.join(os.getcwd(), "example.txt"))

이렇게 하면 파일 이름, 크기 및 마지막 수정 시간이 형식화된 방식으로 출력됩니다.

오류 및 예외 처리

권한 문제 다루기

파일 및 디렉토리 작업 중에 권한 관련 오류가 발생할 수 있습니다. 이러한 예외를 처리하기 위해 try-except 블록을 사용할 수 있습니다:

import os
 
try:
    restricted_file = os.path.join(os.getcwd(), "restricted.txt")
    file_size = os.path.getsize(restricted_file)
    print(f"파일 크기: {file_size} 바이트")
except PermissionError:
    print(f"오류: {restricted_file}에 대한 액세스 권한이 없습니다.")

이 코드는 "restricted.txt" 파일의 크기를 가져오려고 시도하고, PermissionError가 발생하면 오류 메시지를 출력합니다.

OSError 예외 처리하기

os 모듈은 다양한 파일 및 디렉토리 관련 문제에 대해 OSError 예외를 발생시킬 수 있습니다. 이러한 예외를 처리할 수 있습니다:

import os
 
try:
    nonexistent_file = os.path.join(os.getcwd(), "nonexistent.txt")
    file_size = os.path.getsize(nonexistent_file)
    print(f"파일 크기: {file_size} 바이트")
except OSError as e:
    print(f"오류: {e}")

이 코드는 "nonexistent.txt" 파일의 크기를 가져오려고 시도하고, OSError가 발생하면(예: 파일이 존재하지 않음) 오류 메시지를 출력합니다.

실용적인 활용

백업 및 아카이브 스크립트

파일 목록 작업 기법을 사용하여 백업 또는 아카이브 스크립트를 생성할 수 있습니다. 예를 들어, 디렉토리와 그 하위 디렉토리의 모든 파일을 하나의 ZIP 파일로 압축하는 스크립트를 생성할 수 있습니다.

import os
import zipfile
 
def backup_directory(directory, zip_filename):
    """
    디렉토리와 그 하위 디렉토리의 모든 파일을 ZIP 아카이브로 만듭니다.
    """
    with zipfile.ZipFile(zip_filename, "w") as zip_file:
        for root, _, files in os.walk(directory):
            for file in files:
                file_path = os.path.join(root, file)
                zip_file.write(file_path)
 
# 사용 예시
backup_directory(os.getcwd(), "backup.zip")
print("디렉토리 백업 완료.")

backup_directory() 함수는 디렉토리 경로와 ZIP 파일 이름을 입력으로 받아, 디렉토리와 그 하위 디렉토리의 모든 파일을 ZIP 아카이브로 만듭니다.

파일 정리 및 정리 도구

파일 목록 및 필터링 기술을 사용하여 디렉토리의 파일을 정리하거나 정리하는 스크립트를 생성할 수 있습니다. 예를 들어, 파일 확장자에 따라 파일을 서브디렉토리로 분류할 수 있습니다.

import os
import shutil
 
def organize_files(directory):
    """
    파일을 확장자에 따라 서브디렉토리로 정리합니다.
    """
    for file in os.listdir(directory):
        if os.path.isfile(file):
            extension = os.path.splitext(file)[1][1:]
            new_directory = os.path.join(directory, extension)
            os.makedirs(new_directory, exist_ok=True)
            new_path = os.path.join(new_directory, file)
            shutil.move(file, new_path)
 
# 사용 예시
organize_files(os.getcwd())
print("파일 정리 완료.")

organize_files() 함수는 디렉토리 경로를 입력으로 받아 파일을 확장자에 따라 서브디렉토리로 정리합니다. 여기는 직사각형의 넓이를 계산하는 간단한 함수의 예입니다:

def calculate_area(length, width):
    area = length * width
    return area
 
# 사용법
rectangle_length = 5
rectangle_width = 3
result = calculate_area(rectangle_length, rectangle_width)
print(f"직사각형의 넓이는 {result} 제곱 단위입니다.")

이 예에서는 calculate_area() 함수가 lengthwidth라는 두 개의 매개변수를 받아들이고, 그들을 곱하여 넓이를 계산합니다. 함수는 계산된 넓이를 반환합니다.

또한 매개변수를 가지지 않고 어떤 값도 반환하지 않는 함수를 정의할 수도 있습니다:

def greet_user():
    print("안녕하세요, 사용자님!")
 
# 사용법
greet_user()

함수는 기본 매개변수 값을 가질 수도 있으며, 이로 인해 더 유연하게 사용할 수 있습니다:

def calculate_circle_area(radius, pi=3.14159):
    area = pi * radius ** 2
    return area
 
# 사용법
circle_radius = 4
result = calculate_circle_area(circle_radius)
print(f"원의 넓이는 {result} 제곱 단위입니다.")
 
# 사용자 정의 pi 값과 함께 사용
result = calculate_circle_area(circle_radius, pi=3.14)
print(f"원의 넓이는 {result} 제곱 단위입니다.")

이 예에서 calculate_circle_area() 함수는 pi 매개변수의 기본값을 3.14159로 가지고 있지만, 필요한 경우 사용자 정의 값을 전달할 수도 있습니다.

모듈과 패키지

Python의 모듈화된 디자인을 통해 코드를 재사용 가능한 구성 요소인 모듈로 구성할 수 있습니다. 모듈은 함수, 클래스 및 변수를 포함하는 Python 파일입니다. 모듈을 가져와서 자체 코드에서 제공하는 기능을 사용할 수 있습니다.

내장된 math 모듈을 사용하는 방법의 예입니다:

import math
 
# 사용법
radius = 5
circle_area = math.pi * radius ** 2
print(f"원의 넓이는 {circle_area:.2f} 제곱 단위입니다.")

이 예에서 math 모듈을 가져오고 pi 상수를 사용하여 원의 넓이를 계산합니다.

특정 함수 또는 변수를 모듈에서 가져올 수도 있습니다:

from math import pi, sqrt
 
# 사용법
radius = 5
circle_area = pi * radius ** 2
square_root = sqrt(25)
print(f"원의 넓이는 {circle_area:.2f} 제곱 단위입니다.")
print(f"25의 제곱근은 {square_root}입니다.")

이 방법을 사용하면 math. 모듈 이름을 접두어로 사용하지 않고 pisqrt() 함수에 바로 접근할 수 있습니다.

Python은 관련된 모듈의 모음인 패키지도 지원합니다. 패키지를 사용하면 코드를 계층적 구조로 구성하여 소프트웨어를 관리하고 배포하기 쉽게 만들 수 있습니다.

간단한 패키지를 만드는 방법의 예입니다:

my_package/
    __init__.py
    math_utils.py
    string_utils.py

이 예에서 my_package는 패키지이며, math_utils.pystring_utils.py는 패키지 내의 모듈입니다. __init__.py 파일은 디렉토리를 패키지로 표시하는 데 필요합니다.

그런 다음 패키지 내의 모듈에서 함수를 가져와 사용할 수 있습니다:

from my_package.math_utils import calculate_area
from my_package.string_utils import reverse_string
 
# 사용법
rectangle_area = calculate_area(5, 3)
print(f"직사각형의 넓이는 {rectangle_area} 제곱 단위입니다.")
 
reversed_text = reverse_string("Python")
print(f"반전된 문자열은: {reversed_text}입니다.")

코드를 모듈 및 패키지로 구성하면 유지 관리가능한 활용 가능한 배포 가능한 코드가 됩니다.

예외 처리

Python에서 예외는 프로그램의 실행 중에 발생하는 일반적인 흐름을 방해하는 이벤트입니다. 예외 처리는 견고하고 신뢰할 수 있는 코드를 작성하는 데 중요한 측면입니다.

ZeroDivisionError 예외를 처리하는 방법의 예입니다:

def divide_numbers(a, b):
    try:
        result = a / b
        return result
    except ZeroDivisionError:
        print("오류: 0으로 나눌 수 없습니다.")
        return None
 
# 사용법
dividend = 10
divisor = 0
result = divide_numbers(dividend, divisor)
if result is not None:
    print(f"{dividend} / {divisor}의 결과는 {result}입니다.")
else:
    print("나눗셈을 수행할 수 없습니다.")

이 예에서 divide_numbers() 함수는 a 매개변수를 b 매개변수로 나누려고 시도합니다. b가 0이면 ZeroDivisionError 예외가 발생하며, 이를 함수가 처리하여 오류 메시지를 출력하고 None을 반환합니다.

단일 try-except 블록에서 여러 예외를 처리할 수도 있습니다:

def process_input(user_input):
    try:
        value = int(user_input)
        return value
    except ValueError:
        print("오류: 잘못된 입력입니다. 숫자를 입력해주세요.")
        return None
    except Exception as e:
        print(f"예상치 못한 오류가 발생했습니다: {e}")
        return None
 
# 사용법
user_input = input("숫자를 입력해주세요: ")
result = process_input(user_input)
if result is not None:
    print(f"입력된 값은: {result}입니다.")

이 예에서 process_input() 함수는 먼저 int() 함수를 사용하여 user_input을 정수로 변환하려고 합니다. 입력이 유효한 숫자가 아닌 경우 ValueError 예외가 발생하며, 이는 오류 메시지를 출력하고 None을 반환하여 처리됩니다. 또한 함수는 예상치 못한 다른 예외도 출력을 통해 처리합니다.

예외 처리는 예상치 못한 상황을 우아하게 처리할 수 있는 견고하고 사용자 친화적인 애플리케이션을 만드는 데 매우 중요합니다.

파일 I/O

Python은 파일에서 읽거나 파일에 쓰기 위한 내장 함수와 메서드를 제공합니다. 이를 통해 데이터를 유지하고 파일 시스템과 상호작용할 수 있습니다.

파일에서 읽는 방법의 예입니다:

# 파일에서 읽기
with open("example.txt", "r") as file:
    content = file.read()
    print(f"파일 내용:\n{content}")

이 예시에서 open() 함수는 "example.txt" 파일을 읽기 모드인 "r"로 엽니다. with 문은 예외가 발생해도 코드 블록이 실행된 후 파일을 정상적으로 닫도록합니다.

파일을 한 줄씩 읽을 수도 있습니다.

# 파일을 한 줄씩 읽기
with open("example.txt", "r") as file:
    for line in file:
        print(line.strip())

이 예제는 파일을 한 줄씩 읽고 strip() 메소드를 사용하여 선행 및 후행 공백을 제거한 후 각 줄을 출력합니다.

파일에 쓰려면 쓰기 모드 ("w") 또는 추가 모드 ("a")를 사용할 수 있습니다.

# 파일에 쓰기
with open("output.txt", "w") as file:
    file.write("첫 번째 줄입니다.\n")
    file.write("두 번째 줄입니다.\n")
 
# 파일에 추가하기
with open("output.txt", "a") as file:
    file.write("파일에 추가된 새로운 줄입니다.\n")

첫 번째 예시에서는 "output.txt" 파일을 쓰기 모드로 열고 두 줄의 텍스트를 씁니다. 두 번째 예시에서는 동일한 파일을 추가 모드로 열고 파일 끝에 새로운 줄을 추가합니다.

파일 입출력은 설정 파일 읽기, 데이터 기록, 응용 프로그램 상태 저장/로드 등의 작업에 필수적입니다.

결론

이 튜토리얼에서는 함수, 모듈과 패키지, 예외 처리, 파일 입출력을 포함한 다양한 중급 Python 개념에 대해 알아보았습니다. 이러한 주제는 보다 복잡하고 견고한 Python 응용 프로그램을 구축하는 데 필수적입니다.

함수를 이해함으로써 재사용 가능하고 모듈화된 코드를 작성하여 유지 및 확장하기 쉬운 코드를 생성할 수 있습니다. 모듈과 패키지는 코드를 구성하여 더 관리하기 쉽고 공유할 수 있게 도와줍니다. 예외 처리는 예상치 못한 상황에 대처할 수 있는 신뢰할 수 있는 소프트웨어 작성에 중요합니다. 마지막으로, 파일 입출력 작업을 통해 데이터를 영구적으로 보관하고 상호 작용할 수 있습니다. 이는 많은 실제 응용 프로그램에 중요합니다.

Python을 탐색하고 연습하면서 이러한 개념을 실험하고 다양한 사용 사례를 시도하며 지식을 지속적으로 확장해 나가기를 권장합니다. Python의 다양성과 다양한 라이브러리와 프레임워크 생태계는 웹 개발부터 데이터 분석 등 다양한 응용 분야에 강력한 언어로 사용될 수 있도록 합니다.

MoeNagy Dev