본문 바로가기
파이썬/기초 학습

Day 3: 함수 정의 & 파일 처리 학습

by CBROJIN 2025. 7. 24.

1) 학습 요약표

학습 내용 설명
함수 정의와 호출 def로 함수 정의, 매개변수와 return으로 값 반환
파일 열기 모드 open() 함수의 모드(r, w, a, r+)와 encoding 옵션
안전한 파일 처리 with open()으로 파일 자동 닫기 처리
파일 존재 여부 확인 os.path.exists()로 파일 유무 확인
파일 쓰기와 즉시 저장 flush()로 버퍼 즉시 디스크 저장
 

2) 이론 설명

(1) 함수 정의와 호출

기능 설명:
함수는 반복해서 써야 하는 코드를 한 번만 작성해두고, 필요할 때마다 불러 쓸 수 있게 해주는 도구.
입력값(매개변수)을 받아서 계산하거나 작업을 한 뒤, return으로 결과를 돌려줌.
이렇게 하면 같은 코드를 여러 번 복사할 필요 없이 함수를 호출만 해서 재사용.

 

동작 원리:

  1. def 키워드로 함수 이름과 동작을 정의한다.
  2. 함수 이름을 호출할 때, 필요한 값(인자)을 넣어주면 그 값들이 함수 안으로 들어가 로컬 스코프(Local Scope)라는 독립된 공간에서 처리된다.
  3. 함수 안에서 작업이 끝나면 return으로 결과를 돌려주고, 함수는 종료된다.
  4. 돌려받은 결과는 변수에 저장하거나 바로 출력할 수 있다.
def get_device_status(device_name, status):
    message = f"장비 {device_name} 현재 상태: {status}"
    return message

dev_msg = get_device_status("R01", "정상")
print(dev_msg)

줄 단위 설명:

1. def get_device_status(device_name, status):

  • get_device_status라는 이름의 함수를 정의한다.
  • 이 함수는 device_name과 status라는 두 개의 입력값(매개변수)을 받아서 동작한다.

2. message = f"장비 {device_name} 현재 상태: {status}"

  • f-string을 사용해서 입력받은 값들을 문자열 안에 넣어, 사람이 읽기 좋은 문장으로 만든다.

3. return message

  • 만든 메시지를 함수 밖으로 돌려준다.
  • return이 없으면 함수가 결과를 외부에 넘기지 못하고, 호출한 쪽에서는 아무것도 못 받는다.

4. dev_msg = get_device_status("R01", "정상")

  • 정의해둔 함수를 실제로 호출한다.
  • "R01"이 device_name으로, "정상"이 status로 전달된다.
  • 함수 실행이 끝나면 return으로 돌려준 메시지가 dev_msg에 저장된다.

5. print(dev_msg)

  • 함수가 돌려준 메시지를 화면에 출력한다.
  • 결과는 장비 R01 현재 상태: 정상 이라는 문자열이다.
 

(2) 파일 열기 모드와 동작 원리

기능 설명:
open() 함수는 파일을 열어서 읽거나 쓰는 작업을 할 수 있게 해주는 함수.
파일을 열 때 어떤 용도로 열 것인지(읽기, 쓰기, 덧붙이기 등)를 모드라는 옵션으로 지정.

모드별 동작:

  • r : 읽기 전용 모드.
    이미 존재하는 파일을 읽을 때만 사용. 파일이 없으면 오류.
  • w : 쓰기 전용 모드.
    파일이 있으면 기존 내용이 모두 지워지고 새로 작성됨. 파일이 없으면 새로 만들어짐.
  • a : 추가(append) 모드.
    기존 내용은 그대로 두고, 파일 끝에 새 내용을 덧붙인다.
  • r+ : 읽기/쓰기 겸용 모드.
    파일이 반드시 존재해야 하며, 기존 내용을 읽거나 수정할 수 있다.

동작 원리:

  1. open()으로 파일을 열면, 운영체제가 그 파일을 메모리 버퍼와 연결.
    버퍼는 파일과 프로그램 사이에서 데이터를 임시로 보관하는 메모리 공간.
  2. read()를 호출하면, 파일 내용이 버퍼를 거쳐 프로그램으로 들어오고,
    write()를 호출하면, 데이터가 먼저 버퍼에 쌓임.
  3. flush()를 호출하거나, close()로 파일을 닫을 때, 버퍼의 내용이 실제 디스크(파일)에 저장됨.
    (flush() 없이 close()만 해도 자동으로 저장됨)
log_file = open("device_log.txt", "w", encoding="utf-8")
log_file.write("[INFO] 장비 R01 상태 정상\n")
log_file.flush()
log_file.close()
 

(3) 안전한 파일 처리 (with open())

기능 설명:
with open()은 파일을 열고, 자동으로 닫아주는 방식.
일반적으로 open()을 쓴 뒤에는 close()를 직접 호출해야 하는데,
코드 중간에 오류가 나거나, return으로 함수가 일찍 끝나면 close()가 안 불려서 파일이 열려 있는 상태로 남을 수 있다.
이러면 파일이 손상되거나, 다른 프로그램이 접근 못 하는 문제가 생긴다.

with open()을 쓰면:

  • with 블록 안에서만 파일을 열고,
  • 블록을 빠져나오는 순간(정상 종료든, 오류든 상관없이) 자동으로 파일을 닫아준다.
    그래서 파일 누수 문제 없이 안전하게 처리할 수 있다.

동작 흐름:

1. with open("파일이름", "모드", encoding="utf-8") as f:

  • 지정한 파일을 특정 모드(r, w, a 등)로 열고, 그 파일 객체를 f라는 변수로 다룸.

2. 들여쓰기 된 블록 안에서 f.read(), f.write() 같은 작업을 수행.

3. 블록을 빠져나오면 f.close()가 자동으로 호출돼서 파일이 안전하게 닫힘.

# 안전하게 파일 읽기
with open("device_log.txt", "r", encoding="utf-8") as f:
    content = f.read()
    print(content)
# with 블록을 벗어나면 자동으로 파일 닫힘
 

(4) 파일 존재 여부 확인 (os.path.exists())

기능 설명:
os.path.exists() 함수는 지정한 경로(파일이나 폴더)가 실제로 존재하는지 확인할 때 사용해.
이걸 사용하면

  • 파일이 없을 때 프로그램이 에러로 멈추는 걸 막을 수 있고,
  • 파일이 있으면 읽거나 수정, 없으면 새로 만드는 식으로 조건을 나눠서 안전하게 동작할 수 있어.

동작 흐름:

1. import os

  • 파이썬의 os 모듈을 불러옴. (운영체제 관련 기능을 제공하는 표준 라이브러리)

2. os.path.exists("경로")

  • 지정한 경로가 실제로 있는지(True/False로 확인)
  • 파일이든 폴더든 모두 검사 가능.

3. 결과에 따라 if문으로 다른 동작을 하게 만들 수 있음.

import os

if os.path.exists("device_log.txt"):
    print("로그 파일이 존재합니다.")
else:
    print("로그 파일이 없습니다.")
 

3) 기본 실습 과제

과제 1: 장비 로그 파일 생성

문제 설명: devices 리스트에 R01, SW01, FW01 있다.

각 장비 상태를 "정상"으로 기록하는 로그 파일(status_log.txt)을 생성하고 내용 확인.

 

과제 2: 파일 존재 여부 확인 후 작성

문제 설명: device_config.txt가 없으면 새로 만들고, 있으면 "이미 존재" 출력.

 

과제 3: 사용자 입력으로 로그 기록

문제 설명: 사용자로부터 장비 이름과 상태를 입력받아 input_log.txt에 한 줄씩 기록. 3회 반복 입력 후 파일 내용 출력.

 

과제 4: 로그 파일에 덧붙이기

문제 설명: status_log.txt 파일에 새로운 장비 AP01 상태(정상)를 추가 기록.

 

과제 5: 로그 검색

문제 설명: status_log.txt에서 "정상"이 포함된 줄만 출력.

 

과제 6: 함수로 로그 작성 자동화

문제 설명: write_log(device_list, filename) 함수를 만들어 주어진 장비 리스트를 모두 로그 파일에 기록.

작성 후 파일 내용을 출력.

 

4) 심화 실습 과제 (3개)

과제 1: 상태별 장비 분류

문제 설명:  상태별로 장비를 리스트로 묶어 출력.

사용 방식 반환 내용 반복문에서 꺼내는 값 주로 쓰는 경우
for x in devices: 키(key)만 반환 R01, SW01, FW01, AP01 키만 필요할 때 (기본 순회)
for x in devices.keys(): 키(key)만 반환 (위와 동일) R01, SW01, FW01, AP01 키를 명시적으로 다루고 싶을 때
for x in devices.values(): 값(value)만 반환 정상, 점검 중, 정상, 오류 값만 모아서 처리할 때 (예: 상태별 개수 세기)
for x, y in devices.items(): 키와 값 쌍 (튜플) ("R01", "정상"), ("SW01", "점검 중") … 키와 값을 동시에 써야 할 때 (상태별 그룹화 등)
 

과제 2: 로그 파일에서 특정 단어 개수 세기

문제 설명: status_log.txt에서 "정상"이 등장한 횟수를 출력.

 

과제 3: 로그 백업 및 원본 삭제

문제 설명: status_log.txtbackup_status.txt로 복사하고 원본 삭제.