|
|
10장 파일과 예외처리
파일의 기초
프로그램에서 만든 데이터를 영구히 저장하기 위해서는 디스크에 파일 형태로 저장하여야 한다. 파일은 보조기억장치 상에서
논리적인 정보 단위로, 보조기억 장치의 물리적인 특성과는 별개의 일관적인 논리적 인터페이스를 제공한다. 또한, 운영체제는
파일 조작에 관련돤 기능을 라이브러리로 제공한다. 파일 안에는 바이트들이 순차적으로 저장되어 있고 맨 끝에 EOF(end of file)
마크가 있다. 파일을 열고 닫는 함수는 open()과 close() 가 있고, 열때는 r, w, a, r+와 같은 모드들이 있는데, 모드에 따라 파일을
제어할 수 있는 권한을 다르게 부여받는다. 이때 \를 문자열 안에 포함해야 할 경우 앞에 \를 붙여 표현할 수 있다.
텍스트 파일 입출력 방법
먼저 파일의 내용을 출력하는 방법에는 readline() 과 for-each 구문을 사용하는 방법이 있다. 먼저 readline()은 파일의 내용 중 한 줄을 출력하는 방식이다. for-each문의 경우는 위 방식은 간편하게 구현한 것으로, 파일의 모든 줄을 차례대로 읽어 출력한다.
입력의 경우 open()함수를 호출할 때 파일명과 w, 또는 a 모드로 호출하면 된다. w로 호출할 경우 기존의 데이터는 모두 삭제되고 입력된 데이터로 덮어씌워지므로 사용에 주의해야 한다. 텍스트 파일을 처리할 때는 문자 인코딩 방식을 확인해야 하는데,
인코딩 방식에 따라 통일한 타일이라도 바이트 수가 달라지기 때문이다. 과거의 텍스트 파일은 거의ANSI 코드이며, 외국과
텍스트 파일을 교환할 경우 호환성이 좋은 UTP-8 방식으로 인코딩하는 것이 좋다.
| 인코딩 방식 | 용도 | 호환성 | 범용성 | 효율성 | 글로벌 지원 범위 |
| **UTF-8** | 유니코드, 1991년에 전 세계 문자를 지원하기 위한 표준 중 하나로 가변 길이 인코딩 방식으로 개발됨. | 5 | 5 | 4 | 5 |
| ASCII | 미국에서 1960년대 초반, ANSI(미국 국가 표준 협회)에서 개발. 7비트 문자 집합으로, 주로 영어 텍스트와 기호를 표현하기 위해 만들어짐. | 5 | 1 | 5 | 1 |
| ISO-8859-1 | ISO에서 1987년에 제정. 주로 서유럽 언어에 사용되며, 8비트 인코딩을 사용하여 각 언어의 특수 문자를 지원. | 4 | 3 | 3 | 3 |
| UTF-16 | 유니코드, 1990년대 초반 제작. 16비트 단위로 문자를 표현하며, 유니코드 기반으로 다양한 문자를 표현하기 위해 개발됨. | 3 | 4 | 3 | 5 |
디렉토리 작업
파일을 처리하다 보면 파일 전체를 찾아 처리해야 하는 경우에 os모듈에서 제공하는 도구들을 사용할 수 있다.
대표적으로 os.chdir(), os.listdir(), os.andswidth() 등이 있다.
이진 파일과 임의 접근 파일
파일과 이진 파일의 차이점은 데이터가 문자나 숫자로 변환되지 않은 데이터 본연의 상태로 저장되어 있다는 것이다. 이러한
경우 파일을 읽을 때 읽어야 할 데이터의 타입, 즉 문자나 숫자로의 형변환을 할 필요가 사라져 효율적일 뿐만 아니라 데이터의
용량 또한 절약할 수 있다. 그러나 인간이 내용을 확인하기가 어렵고 모니터나 프린터로 출력하는 것이 불가능하다. 또한,
하드웨어마다 이진 데이터를 다루는 방식이 다를 수 있어 이식성이 떨어진다. 파일 입출력 방법은 순차 접근과 임의 접근
방식이 존재한다. 앞서 배운 방식의 경우 데이터를 파일의 처음부터 읽거나 기록하는 순차 접근 방식의 입출력 방식이다.
임의 접근 방식은 파일의 어느 위치에서든지 읽기와 쓰기가 가능해 더욱 편리하다.
모든 파일에 존재하는 파일 포인터는 읽기와 쓰기 동작이 어디에서 이루어지는지를 나타낸다. 새 파일이 만들어질 때 파일
포인터는 값이 0이고 이것은 파일의 시작 부분을 나타낸다. 기존 파일 접근 방식에서의 추가 모드로 호출 시에는 파일의 끝을
가리키고, 다른 모드일 경우에는 파일의 처음을 가리킨다. 이때 tall()을 사용하여 현재 위치 표시자의 위치를 알 수 있고, seek() 을 이용하여 위치를 조작할 수 있다.
객체 출력
딕셔너리와 같은 객체를 출력할 때는 pickle 모듈을 주로 사용한다. 이 모듈의 dump()와 load()를 사용하여 객체를 읽고 쓸 수
있다. 객체를 pickle 모듈로 압축하려면 dump()를 사용한다. 먼저 파일 안에 객체를 넣고, dump()에 객체명과 파일 이름을
작성해주면 된다.
정규식
정규식이란 특정한 의미를 가지는 기호로 파일의 이름을 정확하게 알 수 없을 때 사용한다. 정규식은 상당히 다양하고 많아
자주 쓰이는 기호들만 추려 외워놓는 편이 좋다.
예외 처리
오류가 발생하였을 경우 우리는 먼저 파이썬이 보고하는 오류의 내용을 살펴볼 수 있다. 이러한 오류 메세지를 역추적 메세지 라고 한다. 파이썬에서 실행 도중에 발생하는 오류를 예외 라고 하는데, 이때 발생한 오류를 사용자에게 알려주고 모든 데이터를 저장한 뒤에 안전하게 프로그램을 종료할 수 있도록 하는 것이 바람직하다. 그에 더해 오류를 처리한 후에 계속 실행할 수
있다면 더욱 좋을 것이다. 파이썬에서는 예외처리를 통하여 이러한 기능을 제공할 수 있다. 일반적인 오류의 종류는 사용자의
입력 데이터가 잘못되어 일어나는 사용자 입력 오류, 네트워크나 메모리의 작동 오류로 인한 장치 오류, 코딩 과정에서의 코드 오류가 발생할 수 있다. 오류를 처리하는 방법은 메소드에서 오류 코드를 반환하는 것과 try-execpt블록을 사용하여 오류가 발생하면 오류를 설명하는 예외가 생성되며 이 예외가 오류 처리 코드로 전달된다. 기본 원리는 이러하다.
먼저 오류가 발생할 수 있는 코드를 try블록에 배치한 뒤 여러 오류 발생 경우에 따른 각각의 대비 코드들을 execpt 블록에
배치하여 오류가 생길 경우 대응되는 execpt 블록이 실행되어 실행 시간에 오류에 대응할 수 있게 된다. 이 외에도 오류가
발생하지 않았을 때를 대비하여 작성하는 else 블록과 오류와 관계없이 항상 실행되는 finally 블록이 있다.
python_10_func.py)
# 1
# 함수 X
# 2
# 함수 X
# 3
def read_file(filename, row):
cnt = 1
file = open(filename, "r")
for line in file:
if cnt == row:
print(f"{row}번 행은 {line}입니다.")
cnt += 1
file.close()
# 4
# 함수 X
# 5
# 함수 X
# 6
# 함수 X
# 7
def open_file() :
filename = input("입력 파일 이름:")
try:
with open(f"{filename}", "r") as f:
print("파일이 성공적으로 열렸습니다.")
f.close()
except:
print(f"파일 {filename} 이 없습니다. 다시 입력하시오.")
open_file()
# 8
def add_avg(filename) :
cnt = 0
sum = 0
with open(filename, "r+", encoding="UTF-8") as f:
for score in f:
sum += float(score)
cnt += 1
print(f"{score}, {sum}, {cnt} \n")
f.write(f"평균값: {sum/cnt}\n")
# 9
def del_str():
filename = input("파일 이름을 입력하시오.")
target = input("삭제할 문자열을 입력하시오.")
with open(filename, "r") as f:
lines = f.readlines()
new_lines = [line.replace(target, "") for line in lines]
with open(filename, "w") as f:
f.writelines(new_lines)
# 10
def cnt_void():
cnt_space = 0
cnt_tap = 0
filename = input("파일 이름을 입력하시오.")
with open(filename, "r") as f:
for contect in f.read():
if contect == " ":
cnt_space += 1
elif contect == "\t":
cnt_tap += 1
print(f"공백 문자 개수: {cnt_space}")
print(f"탭 문자 개수: {cnt_tap}")
# 11
def write_linenum() :
filename = input("파일 이름을 입력하시오.")
with open(filename, "r") as f:
numed_line = [f"{i+1}: {line}" for i, line in enumerate(f)]
with open(filename, "w") as f:
f.writelines(numed_line)
# 12
def replace_words():
words = input("트윗 문자열:")
senc_words = [ ' ' if w == "RT" or w[0] in "@#" else w for w in words.split() ]
print(f"정제된 문자열: {senc_words}")
python_10_main.py)
import python_10_func as func
import random
def main():
# 1
file = open("test.txt", "r")
for _ in range(3):
line = file.readline().rstrip()
print(line)
file.close()
# 2
lst = []
file = open("test.txt", "r")
for line in file:
lst += line.split()
print(f"가장 긴 단어는 {max(lst, key=len)}입니다")
file.close()
# 3
name = input("파일 이름을 입력하시오")
row = int(input("행 번호를 입력하시오"))
func.read_file(name, row)
# 4
lst = "abcdefghijklmnopqrstuvwxyz"
for i in lst:
with open(f"{i}.txt", "w"):
pass
# 5
with open("test.txt", "r") as f:
lines = f.readlines()
f.close()
lines.insert(2, "2-1\n")
with open("test.txt", "w") as f:
f.writelines(lines)
f.close()
# 6
with open("numbers.txt", "w") as f:
for _ in range(10):
f.write(f"{random.randint(1, 100)}\n")
f.close()
# 7
func.open_file()
# 8
scores = [99.1, 88.2, 67.7, 96.9]
with open("score.txt", "w", encoding="UTF-8") as f:
for score in scores:
f.write(f"{score}\n")
func.add_avg("score.txt")
# 9
func.del_str()
# 10
func.cnt_void()
# 11
func.write_linenum()
# 12
func.replace_words()
if __name__ == "__main__":
main()
|
|

첫댓글 0. 텍스트파일과 이진파일의 핵심 차이는 무엇인가?
1. import python_10_func as func -> 이문장을 실행할때 일어나는 일을 자세히 설명하라. 파이썬 인터프리터가 python_10_func 모듈을 어떻게 찾는지 sys.path의 기능과 연결하여 설명하라.
2. 파이썬에서 문자인코딩을 설정하는 방법을 설명하라. 유니코드 or 아스키코드
3. 파일입출력은 왜 필요한가 키보드로 입력받고 모니터에 출력하는 방식과 뭐가 다른가?
4. 스트림, 스트림 버퍼의 역할을 조사하라,
5 프로그램<->스트림, 스트림<->파일(or 키보드,모니터)의 통신은 어떻게 이루어지는지 조사하라