파일에 문자열 쓰기
- 파일에 문자열을 쓸 때는 open함수로 파일을 연 후 객체를 얻은 후에 write메서드를 사용합니다.
- 파일 모드를 w로 지정해줍니다. (write)
file_write_string.py
#hello.txt 파일을 쓰기 모드(w)로 열기, 파일 객체 반환
file = open('hello.txt', 'w')
#파일에 문자열 저장
file.write('Hello, world!')
#파일 객체 닫기
file.close()
- 코드를 실행하면 해당 파이썬 파일이 위치해 있는 폴더에 hello.txt파일이 생성됩니다.
hello.txt
Hello, world!
- 파일을 열어보면 'Hello, world!'라고 저장되어 있는 것을 확인하실 수 있습니다.
파일에 문자열 읽기
- 앞서 hello.txt 파일의 문자열을 읽는 방법입니다. 파일에 문자열을 작성할 때와 동일하게 open함수로 파일을 열어 객체를 얻은 뒤 read메서드로 파일의 내용을 읽을 수 있습니다.- 이때는 파일 모드를 'r'로 지정해줍니다.(read)
file_read_string.py
#hello.txt 파일을 읽기 모드(r)로 열기, 파일 객체 반환
file = open('hello.txt', 'r')
#파일에서 문자열 읽기
s = file.read()
#Hello, world!
print(s)
#파일 객체 닫기
file.close()
>> Hello, world!
- 파일을 읽기 모드(r)로 열어서 반환값을 변수에 저장해주면 파일의 내용을 읽을 수 있습니다.
자동으로 파일 객체 닫기
- 파일을 열 때마다 매번 close로 닫기 귀찮을 경우 with as를 사용하면 자동으로 파일 객체를 닫아줍니다.
with open(파일이름, 파일모드) as 파일 객체:
코드
- with 다음에 open으로 파일을 열고 as 뒤에 파일 객체를 지정하면 위에서 설명했던 기능들과 같은 기능을 수행합니다.
❗file.close()를 해줘야 하는 이유?
- 파이썬에서는 사용이 끝난 메모리를 정리해주는 가비지 컬렉터가 있어서 파일을 닫지 않아도 가비지 컬렉터가 파일을 닫아주지만 프로그래머는 파일을 직접 닫아야 하는 이유가 있습니다.
1. 너무 많은 파일을 열어 두면 그만큼 메모리 공간을 차지하므로 성능에 영향을 줄 수 있습니다.
2. 파일을 닫지 않으면 데이터 쓰기가 완료되지 않을 수도 있습니다.
3. 이론적으로 운영체제에서 열 수 있는 파일의 개수는 한계가 있기 때문입니다.
파일 모드
파일 모드 | 기능 | 설명 |
'r' | 읽기 전용 | 파일을 읽기 전용으로 열기, 단, 파일이 반드시 있어야 하며 파일이 없으면 에러 발생 |
'w' | 쓰기 전용 | 쓰기 전용으로 새 파일을 생성, 만약 파일이 있으면 내용을 덮어씀 |
'a' | 추가 | 파일을 열어 파일 끝에 값을 이어 씀. 만약 파일이 없으면 파일을 생성 |
'x' | 배타적 생성(쓰기) | 파일을 쓰기 모드로 생성, 파일을 이미 있으면 에러 발생 |
'r+' | 읽기/쓰기 | 파일을 읽기/쓰기용으로 열기, 단 파일이 반드시 있어야 하며파일이 없으면 에러 발생 |
'w+' | 읽기/쓰기 | 파일을 읽기/씌용으로 열기, 파일이 없으면 파일을 생성하고, 파일이 있으면 내용을 덮어씀 |
'a+' | 추가(읽기/쓰기) | 파일을 열어 파일 끝에 값을 이어 씀. 만약 파일이 없으면 파일을 생성, 읽기는 파일의 모든 구간에서 기능하지만 쓰기는 파일의 끝에서만 가능함 |
'x+' | 배타적 생성(읽기/쓰기) | 파일을 읽기/쓰기 모드로 생성, 파일이 이미 있으면 에러 발생 |
t | 텍스트 모드 | 파일을 읽거나 쓸 때 개행 문자 \n과 \r\n을 서로 변환 t를 생략하면 텍스트 모드 |
b | 바이너리 모드 | 파일의 내용을 그대로 읽고, 값을 그대로 씀 |
학생 관리 프로그램 만들기
등록 메서드
class Information:
def __init__(self, name, stu_num, kor, eng, mat):
self.name = name
self.stu_num = stu_num
self.kor = kor
self.eng = eng
self.mat = mat
#등록메서드
def info(self, name, stu_num, kor, eng, mat):
with open('Student.txt', 'w') as file:
file.write("이름: {0} 학번: {1} 국어: {2} 영어: {3} 수학: {4} 평균: {5}\n".format(name ,stu_num ,kor ,eng ,mat ,(kor+eng+mat)/3))
file.close()
def info_a(self, name, stu_num, kor, eng, mat):
with open('Student.txt', 'a') as file:
file.write("이름: {0} 학번: {1} 국어: {2} 영어: {3} 수학: {4} 평균: {5}\n".format(name ,stu_num ,kor ,eng ,mat ,(kor+eng+mat)/3))
file.close()
- 클래스를 생성한 뒤 초기화 메서드를 만들어 주고 txt파일에 받아온 데이터들을 넣었습니다.
수정 메서드
# 학번을 기준으로 학생 정보를 수정하는 메서드
def modify_info(self, stu_num, kor, eng, mat):
with open('Student.txt', 'r') as file:
lines = file.readlines()
# 해당 학번의 학생 정보를 찾아서 수정
for i, line in enumerate(lines):
if f"학번: {stu_num}" in line:
name = line.split()[1]
lines[i] = f"이름: {name} 학번: {stu_num} 국어: {kor} 영어: {eng} 수학: {mat} 평균: {(kor + eng + mat) / 3}\n"
break
# 수정된 정보를 파일에 씁니다.
with open('Student.txt', 'w') as file:
file.writelines(lines)
- 수정할 학번 값을 받아와 txt데이터에 동일한 학번 값이 있다면 한 라인을 불러와주고 그 위에 수정할 값을 덮어씌워줍니다.
삭제 메서드
# 학번을 기준으로 학생 정보를 삭제하는 메서드
def delete_info(self, stu_num):
with open('Student.txt', 'r') as file:
lines = file.readlines()
# 해당 학번의 학생 정보를 찾아서 삭제
new_lines = []
deleted = False # 학생 정보가 삭제되었는지 여부를 확인하는 플래그
for line in lines:
if f"학번: {stu_num}" in line:
deleted = True
else:
new_lines.append(line)
# 삭제된 정보를 파일에 씁니다.
with open('Student.txt', 'w') as file:
file.writelines(new_lines)
return deleted
#모두 삭제
def remove_all():
with open('Student.txt', "w") as file:
file.write("")
- if f"학번: {stu_num}" 이 txt파일 라인에 있다면 그 라인은 삭제해주는 메서드 입니다.
- 모두 삭제는 txt파일의 모든 값들을 공백으로 처리 해주었습니다.
검색 메서드, 출력 메서드
#학번 검색
def search_info(self, stu_num):
with open('Student.txt', 'r') as file:
for line in file:
if f"학번: {stu_num}" in line:
print(line.strip())
return True
return False
# 전체 학생 정보를 출력하는 메서드
def print_all(self):
with open('Student.txt', 'r') as file:
for line in file:
print(line.strip())
- 위와 같은 메서드들과 비슷한 기능들로 같은 학번이 존재하면 출력해주는 메서드를 작성했습니다.
전체 코드
class Information:
def __init__(self, name, stu_num, kor, eng, mat):
self.name = name
self.stu_num = stu_num
self.kor = kor
self.eng = eng
self.mat = mat
def info(self, name, stu_num, kor, eng, mat):
with open('Student.txt', 'w') as file:
file.write("이름: {0} 학번: {1} 국어: {2} 영어: {3} 수학: {4} 평균: {5}\n".format(name ,stu_num ,kor ,eng ,mat ,(kor+eng+mat)/3))
file.close()
def info_a(self, name, stu_num, kor, eng, mat):
with open('Student.txt', 'a') as file:
file.write("이름: {0} 학번: {1} 국어: {2} 영어: {3} 수학: {4} 평균: {5}\n".format(name ,stu_num ,kor ,eng ,mat ,(kor+eng+mat)/3))
file.close()
# 학번을 기준으로 학생 정보를 수정하는 메서드
def modify_info(self, stu_num, kor, eng, mat):
with open('Student.txt', 'r') as file:
lines = file.readlines()
# 해당 학번의 학생 정보를 찾아서 수정
for i, line in enumerate(lines):
if f"학번: {stu_num}" in line:
name = line.split()[1]
lines[i] = f"이름: {name} 학번: {stu_num} 국어: {kor} 영어: {eng} 수학: {mat} 평균: {(kor + eng + mat) / 3}\n"
break
# 수정된 정보를 파일에 씁니다.
with open('Student.txt', 'w') as file:
file.writelines(lines)
# 학번을 기준으로 학생 정보를 삭제하는 메서드
def delete_info(self, stu_num):
with open('Student.txt', 'r') as file:
lines = file.readlines()
# 해당 학번의 학생 정보를 찾아서 삭제
new_lines = []
deleted = False # 학생 정보가 삭제되었는지 여부를 확인하는 플래그
for line in lines:
if f"학번: {stu_num}" in line:
deleted = True
else:
new_lines.append(line)
# 삭제된 정보를 파일에 씁니다.
with open('Student.txt', 'w') as file:
file.writelines(new_lines)
return deleted
#모두 삭제
def remove_all():
with open('Student.txt', "w") as file:
file.write("")
#학번 검색
def search_info(self, stu_num):
with open('Student.txt', 'r') as file:
for line in file:
if f"학번: {stu_num}" in line:
print(line.strip())
return True
return False
# 전체 학생 정보를 출력하는 메서드
def print_all(self):
with open('Student.txt', 'r') as file:
for line in file:
print(line.strip())
while True:
print("{0:-^50}".format("학생성적 관리 프로그램"))
print("{0:^50}".format("1. 등록, 2. 수정, 3. 삭제, 4. 검색, 5. 전체출력, 6.종료"))
number = int(input())
#등록
if number == 1:
num = int(input("몇명을 등록하시겠습니까? "))
for i in range(num):
name = input("이름을 입력하세요: ")
stu_num, kor, eng, mat = map(int, input("학번, 국어성적, 영어성적, 수학성적을 입력하세요: ").split())
info = Information(name,stu_num,kor,eng,mat)
if i == 0:
info.info(name,stu_num,kor,eng,mat)
else:
info.info_a(name,stu_num,kor,eng,mat)
print("{0:-^50}".format("등록된 학생"))
with open('Student.txt', 'r') as file:
for line in file:
print(line.strip('\n'))
#수정
elif number == 2:
stu_num = int(input("수정할 학생의 학번을 입력하세요: "))
kor, eng, mat = map(int, input("국어성적, 영어성적, 수학성적을 입력하세요: ").split())
info = Information('', stu_num, 0, 0, 0) # 수정 메서드에 접근하기 위해 임시 객체 생성
info.modify_info(stu_num, kor, eng, mat)
print("학생 정보가 수정되었습니다.")
#삭제
elif number == 3:
print("1. 삭제, 2. 전체 삭제")
num = int(input())
if num == 1:
stu_num = int(input("삭제할 학생의 학번을 입력하세요: "))
info = Information('', stu_num, 0, 0, 0) # 삭제 메서드에 접근하기 위해 임시 객체 생성
deleted = info.delete_info(stu_num)
if deleted:
print("학생 정보가 삭제되었습니다.")
else:
print("해당 학번의 학생을 찾을 수 없습니다.")
elif num == 2:
info = Information('', stu_num, 0, 0, 0)
info.remove_all()
elif number == 4:
stu_num = int(input("검색할 학생의 학번을 입력하세요: "))
print("{0:-^50}".format("검색된 학생"))
info = Information('', stu_num, 0, 0, 0) # 검색 메서드에 접근하기 위해 임시 객체 생성
found = info.search_info(stu_num)
if not found:
print("해당 학번의 학생을 찾을 수 없습니다.")
elif number == 5:
print("{0:-^50}".format("전체 출력"))
info = Information('', 0, 0, 0, 0) # 전체 출력 메서드에 접근하기 위해 임시 객체 생성
info.print_all()
elif number == 6:
break
else:
continue
감사합니다!
참조: 파이썬 코딩도장
'Python > Coding' 카테고리의 다른 글
[Python] 파이썬 네이버 뉴스 크롤링 하는 방법 (1) | 2023.11.01 |
---|---|
[Python] 파이썬 코딩도장, 심사문제: 파일 이름을 한꺼번에 바꾸기 (lambda식 사용) (0) | 2023.08.03 |
[Python] 파이썬 for문을 사용해서 별을 찍어보자! 여러가지ver. (0) | 2023.02.27 |