이번 포스팅에서는 다시 파이썬으로 돌아와 os모듈에 대해 알아본다. 파이썬의 os 모듈은 이름에서 알 수 있듯이 운영체제와 상호작용하는 다양한 기능을 제공하는 라이브러리로, 파일과 디렉토리를 관리하거나 시스템 명령어를 실행하는 등의 작업을 할 때 유용하다.
예를 들어, 운영체제 내의 특정 디렉토리의 파일 목록을 가져오거나, 파일 이름을 수정하고, 디렉토리를 생성하거나 삭제할 때 os 모듈을 사용할 수 있다. 따라서 텍스트, 이미지, 파이썬 파일 등 어떤 종류의 파일이든 다룰 수 있다.
os 모듈이 필요한 이유
디렉토리나 파일을 핸들링하는 일은 GUI나 CLI에서도 충분히 가능한데 "굳이 왜" 파이썬 os모듈을 사용해야 하는지 의문이 들 수 있다. 하지만 os 모듈은 우리가 일상에서 하는 많은 노가다 업무를 자동화하는 데 큰 도움을 줄 수 있는 기능이다.
첫째, 반복적 또는 대량의 작업을 자동화할 때 효율적이다. 수백 개 파일 이름을 바꿔야 한다고 할 때, GUI에서 일일이 파일명을 수정하는 노가다를 하는 대신 파이썬 코드로 처리할 수 있다.
둘째, 프로그램의 흐름 안에 파일 시스템 작업을 통합할 수 있다. 무슨 말이냐면, 파일 핸들링을 하기 위해 프로그램을 중간에 멈출 필요 없이, 프로그램 안에 파일 핸들링 작업을 포함해서 코드를 작성할 수 있다는 말이다.
셋째, 플랫폼 독립성을 제공한다. 예를 들어 윈도우와 리눅스의 경로 차이를 자동으로 처리해준다.
구체적인 활용 예시는 글 후반부에 다뤄보기로 하고, 우선 파이썬 os 모듈의 다양한 기능들을 한 번 살펴보자.
os 모듈 사용법과 기능
1. 디렉토리 관련 기능
- os.getcwd(): 현재 작업 디렉토리의 경로를 반환한다.
- os.chdir(경로): 작업 디렉토리를 지정한 경로로 변경한다.
- os.mkdir(디렉토리명): 새로운 디렉토리를 생성한다.
- os.rmdir(디렉토리명): 빈 디렉토리를 삭제한다.
- os.listdir(경로): 지정한 경로 내의 파일과 디렉토리 목록을 리스트로 반환한다.
** 참고로 Window에서는 경로 구분자로 백슬래시(\)를 사용하며, macOS에서는 슬래시(/)를 사용하는데, 이 부분은 os 모듈이 알아서 처리해 반환하기 때문에 딱히 신경쓸 필요는 없다.
코드 작성 예시 (Window 기준)
import os
# 현재 디렉토리 확인
print(os.getcwd()) # 예: "C:\Users\Username\Documents"
# 새 디렉토리 생성
os.mkdir("test_folder")
# 디렉토리로 이동
os.chdir("test_folder")
print(os.getcwd()) # 예: "C:\Users\Username\Documents\test_folder"
# 디렉토리 내 파일 목록 확인
print(os.listdir(".")) # 현재 폴더 내 항목 출력
# 빈 디렉토리 삭제 (이전 디렉토리로 돌아가야 함)
os.chdir("..")
os.rmdir("test_folder")
점 하나(".")와 점 두 개("..")의 의미
위 코드 중 os.listdir(".")와 os.chdir("..")에서 "."와 ".."는 디렉토리 경로를 나타내는 특수한 기호다. 이는 운영 체제와 파일 시스템에서 널리 사용되는 약속 같은 것으로, 파이썬의 os 모듈에서도 그대로 적용된다.
"." (점 하나) : 현재 디렉토리, 즉, 내가 지금 작업하고 있는 폴더를 가리킨다. 예를 들어, 지금 C:\Users\Me 폴더에서 코드를 돌리고 있다면, "."는 바로 그 C:\Users\Me를 뜻한다.
따라서 os.listdir(".") 함수는 현재 디렉토리에 있는 모든 파일과 폴더 목록을 리스트로 반환한다.
".." (점 두 개) : 상위 디렉토리, 즉 현재 디렉토리의 한 단계 위에 있는 폴더를 가리킨다. 예를 들어, 지금C:\Users\Me\Documents에 있다면, ".."는 C:\Users\Me를 뜻한다. 즉, "한 단계 올라가기"다.
따라서 os.chdir("..") 함수는 현재 작업 디렉토리를 상위 디렉토리(\Me)로 변경한다.
2. 파일 관련 기능
- os.rename(기존이름, 새이름): 파일 또는 디렉토리의 이름을 변경한다.
- os.remove(파일명): 파일을 삭제한다.
- os.path.exists(경로): 파일이나 디렉토리가 존재하는지 확인한다. 존재하면 True를 반환한다.
- os.path.isfile(경로): 이 경로가 존재하며, 파일인지 확인한다. 경로가 파일이면 True, 파일이 아니거나 존재하지 않으면 False를 반환한다.
- os.path.isdir(경로): 이 경로가 존재하며, 디렉토리인지 확인한다. 경로가 디렉토리면 True, 디렉토리가 아니거나 존재하지 않으면 False를 반환한다.
코드 작성 예시 (macOS 기준)
import os
# 현재 디렉토리 경로
base_dir = os.getcwd() # 예: "/Users/username/Documents"
# 파일 경로 생성 (슬래시 직접 사용)
file_path = base_dir + "/example.txt"
new_file_path = base_dir + "/renamed_example.txt"
# 파일 생성
with open(file_path, "w") as f:
f.write("테스트 파일")
# 파일 이름 변경
os.rename(file_path, new_file_path)
# 파일 존재 여부 확인
if os.path.exists(new_file_path):
print("파일이 존재한다.") # 출력됨
# 파일인지 확인
if os.path.isfile(new_file_path):
print("이건 파일이다.") # 출력됨
# 디렉토리인지 확인
if os.path.isdir(new_file_path):
print("이건 디렉토리다.") # 출력 안 됨
# 파일 삭제
os.remove(new_file_path)
3. 경로 조작 기능
- os.path.join(경로1, 경로2, ...): 경로를 결합한다.
- os.path.split(경로): 경로를 디렉토리와 파일명으로 나눈다.
- os.path.splitext(경로): 파일명과 확장자를 분리한다.
코드 예시 (macOS 기준)
import os
# 경로 결합
base_dir = "/Users/username"
full_path = os.path.join(base_dir, "Documents", "file.txt")
print(full_path) # 출력: "/Users/username/Documents/file.txt"
# 경로 분리
directory, filename = os.path.split(full_path)
print(directory) # 출력: "/Users/username/Documents"
print(filename) # 출력: "file.txt"
# 파일명과 확장자 분리
name, ext = os.path.splitext(full_path)
print(name) # 출력: "/Users/username/Documents/file"
print(ext) # 출력: ".txt"
4. 시스템 명령어 실행
os 모듈은 시스템 명령어를 실행할 수도 있다. 여기서 '명령어'란 운영 체제의 셸(shell)에서 실행할 수 있는 명령어를 뜻한다. 즉, 터미널(CLI)에서 직접 입력해서 실행할 수 있는 문자열 형식 명령어다. 따라서 명령어는 운영 체제에 따라 다르다.
- os.system(명령어): 지정한 명령어를 실행한다. 반환값은 실행 결과 코드(정수)다.
명렁어란?
명령어는 프로그램 실행, 파일 조작, 시스템 제어 등을 위한 텍스트 기반의 지시다. 형식은 문자열(str)로 작성한다.
os.system()에 전달할 때는 반드시 따옴표(" ") 안에 넣어야 한다. 공백으로 인수를 구분하며, 셸이 이해할 수 있는 문법을 따라야 한다.
** 나는 macOS 사용자이기 때문에 시스템 명령어에 관한 설명은 macOS를 기준으로 함을 참고하시기 바란다.
macOS 명령어 예시
macOS는 Unix 기반이므로 셸 명령어는 주로 Bash나 Zsh 스타일을 따른다. 몇 가지 예시를 들어보면:
- 파일 목록 확인
- 명령어: "ls"
- 파이썬 코드: os.system("ls -l")
- 설명: 파일 목록을 띄워준다. 반환값은 성공하면 0, 일반 오류 시 1, 명령어가 존재하지 않을 시(command not found) 127. 다만 이 함수는 터미널에만 결과를 띄워주고 끝이기 때문에 파이썬에서 활용은 할 수 없다. 파이썬에서 데이터를 다루려면 os.listdir()가 더 나은 선택이다.
- 디렉토리 생성
- 명령어: "mkdir new_folder"
- 파이썬 코드: os.system("mkdir new_folder")
- 설명: 현재 디렉토리에 new_folder라는 디렉토리를 만든다. 성공하면 0을 반환한다.
- 파일 삭제
- 명령어: "rm test.txt"
- 코드: os.system("rm test.txt")
- 설명: test.txt 파일을 삭제한다. 파일이 없으면 에러 코드(예: 1)를 반환한다.
- 시스템 정보 확인
- 명령어: "whoami"
- 코드: os.system("whoami")
- 설명: 현재 사용자 이름을 출력한다. 출력은 터미널에 보이고, 반환값은 0이다.
코드 예시(macOS) 기준
import os
# 1. 파일 목록 확인
result_1 = os.system("ls -l") # macOS에서 셸로 파일 목록을 실행
print(f"파일 목록 확인 반환값: {result_ls}") # 성공 시 0
# 대안: os.listdir() 사용
print(os.listdir("/Users/username"))
# 2. 디렉토리 생성
result_2 = os.system("mkdir new_folder") # 새 디렉토리 생성
print(f"디렉토리 생성 반환값: {result_mkdir}") # 성공 시 0
# 3. 파일 삭제
result_3 = os.system("rm new_folder/test.txt") # 파일 삭제 (파일이 있어야 함)
print(f"파일 삭제 반환값: {result_rm}") # 파일 없으면 1
# 4. 시스템 정보 확인
result_4 = os.system("whoami") # 현재 사용자 이름 출력
print(f"시스템 정보 확인 반환값: {result_whoami}") # 성공 시 0
지금까지 살펴본 바와 같이 os 모듈은 파이썬으로 파일 시스템을 다룰 때 필수적인 도구다.
프로젝트에서도 파일 입출력을 다룰 때 os 모듈을 적극 활용하면 효율적인 코드를 작성할 수 있다.
업무에서의 os모듈 활용 예
도입부에서 언급한 os모듈의 실용성을 직접 보여주는 코드를 한 번 작성해보자.
코드 작성 예시 : 파일명 한 번에 바꾸기
아래 코드는 특정 디렉토리의 모든 파일 이름 뒤에 일괄적으로 "_ver.2" 를 붙여서 변경하는 코드다.
import os
# 파일들이 있는 디렉토리 경로를 지정
directory = "/path/to/your/directory"
# 디렉토리 내의 모든 파일에 대해 반복
for filename in os.listdir(directory):
# 파일의 전체 경로를 구성
file_path = os.path.join(directory, filename)
# 해당 경로가 파일인지 확인
if os.path.isfile(file_path):
# 파일 이름과 확장자를 분리
name, ext = os.path.splitext(filename)
# 새로운 파일 이름을 만듬
new_name = f"{name}_ver.2{ext}"
# 새로운 파일 경로를 구성
new_file_path = os.path.join(directory, new_name)
# 파일 이름을 변경
os.rename(file_path, new_file_path)
print(f"Renamed: {filename} -> {new_name}")
print("모든 파일 이름 변경이 완료되었습니다.")
동작 설명:
- directory = "/path/to/your/directory" : 파일 이름을 변경할 대상 디렉토리의 경로를 지정한다.
- for filename in os.listdir(directory) : os.listdir() 함수를 사용하여 지정된 디렉토리 내의 모든 파일과 디렉토리 이름을 리스트로 가져와서 이 리스트의 각 항목 이름을 filename에 넣는 것을 반복한다.
- file_path = os.path.join(directory, filename) : os.path.join() 함수를 사용하여 디렉토리 경로와 파일 이름을 결합해 전체 파일 경로를 만든다.
- if os.path.isfile(file_path) : os.path.isfile() 함수를 사용하여 현재 항목이 파일인지 확인한다. 폴더(디렉토리)는 처리하지 않기 때문.
- name, ext = os.path.splitext(filename) : os.path.splitext() 함수를 사용하여 파일 이름과 확장자를 분리하여 파일명만 name에 저장한다.
예: "example.txt"는 name="example", ext=".txt"로 분리됨. - new_name = f"{name}_ver.2{ext}" : 원래 파일 이름 뒤에 "_ver.2"를 추가하고 확장자를 붙여 새 파일 이름을 만든다.
- new_file_path = os.path.join(directory, new_name) : 새 파일 이름으로 전체 파일 경로를 다시 구성한다.
- os.rename(file_path, new_file_path) : os.rename() 함수를 사용하여 파일의 이름을 실제로 변경한다.
여기서, 파일명만 새 파일명으로 바꾸면 되지 왜 굳이 전체 파일 경로를 다시 구성해야 하는지 의문이 들 수 있다. (내가 가졌던 의문.. ㅎㅎ) 결론부터 말하면 필수는 아니다. 하지만 오류를 피하기 위해 그렇게 하는 것이 권장되는 것이다.
퍼플렉시티의 답변을 가져와 보면 이해가 된다.
새 파일 이름으로 전체 파일 경로를 다시 구성하는 이유는 다음과 같습니다:
1. 파일 시스템 일관성: os.rename() 함수는 전체 경로를 필요로 합니다. 단순히 파일 이름만 변경하는 것이 아니라, 파일 시스템 내에서 파일의 위치를 정확히 지정해야 합니다
2. 오류 방지: 전체 경로를 사용함으로써 잘못된 위치에 파일을 생성하거나 기존 파일을 덮어쓰는 등의 오류를 방지할 수 있습니다.
3. 유연성: 다른 디렉토리로 파일을 이동하려는 경우에도 같은 코드를 사용할 수 있어 유연성이 높아집니다.
3. 가독성: 전체 경로를 명시적으로 구성함으로써 코드의 의도가 더 명확해지고 가독성이 향상됩니다.
4. 크로스 플랫폼 호환성: os.path.join() 함수를 사용하면 운영 체제에 관계없이 올바른 경로 구분자를 사용할 수 있어 크로스 플랫폼 호환성이 보장됩니다.
따라서 새 파일 이름으로 전체 파일 경로를 다시 구성하는 것은 안전하고 효율적인 파일 조작을 위한 중요한 단계입니다.
네.. .그렇다고 합니다.
예시를 하나 더 들어보려 했지만, 글이 너무 길어질 것 같아 이번 포스팅은 여기서 마친다. 다음에 또 os 모듈에 대해 포스팅할 일이 있기를 바라며...
'AI Journey > 혼자 공부하는 파이썬' 카테고리의 다른 글
[파이썬] OOP - 캡슐화 개념과 데이터 은닉, getter/setter 이해하기 (0) | 2025.04.10 |
---|---|
[파이썬] 다형성(Polymorphism) Part 1. 개념 이해하기 (feat. 우주청소로봇) (0) | 2025.03.07 |
[파이썬] 슬라이싱 기본 규칙 - 문자열, 튜플, 리스트 (0) | 2025.03.05 |
[파이썬] 딕셔너리 - 딕셔너리 내용을 삭제하는 메서드 (0) | 2025.02.21 |
[파이썬] 리스트 - 리스트 내용을 삭제하는 메서드 .remove(), .pop(), clear() 비교 (0) | 2025.02.21 |