[Python]문법 총 정리(3) - 파일 입출력,함수,클래스,예외 처리
카테고리: py
1. 파일 입출력
Definition
- 일반적으로 표준 입출력을 사용하는 프로그램은 키보드로부터 입력을 받아 모니터로 결과를 보냄
- 프로그램이 종료된 이후에도 데이터를 저장하기 위해서 파일 입출력을 사용할 수 있다.
- 파일 객체를 만든 때는 open(), 객체를 닫을 때는 close()
f = open('example.txt', "w")
f.close()
- 파이썬에서눈 여러 가지 파일 모드(mode)를 제공한다,.
- r : 읽기(Read) 모드(파일 읽기)
- w : 쓰기(Write)모드(파일에 내용물 쓰기)
- a : 추가(Append)모드(파일의 마지막에 새로운 내용 추가)
파일 출력, write() 함수
- 파일의 데이터를 쓸 때는 write() 함수를 사용할 수 있다.
- 줄바꿈 기호(\n)을 사용하여, 줄을 변결할 수 있다.
- 여러 줄에 걸쳐서 파일에 데이터를 작설할 수 있다.
file_1 = open("result.txt", "w")
for line in range(1,6):
data = f"{line}번째 줄\n"
f.write(data)
f.close()
파일 읽기, readline(), strip(), read()
- readline() 함수를 이용하면 파이르이 데이터를 한 줄씩 읽을 수 있다.
- 각 줄을 출력할 때 줄의 마지맞에 줄바꿈 기호도 함께 포함된다
- strip()함수를 사용하지 않으면, 두 줄씩 줄바꿈이 수행된다.
[Input]
f = open("result.txt", "r")
while True:
line = f.readline()
if not line: # 더 읽을 문장이 없다면
break
else:
print(line.strip())
f.close()
[Output]
1번째 줄
2번째 줄
3번째 줄
4번째 줄
5번째 줄
- 파일의 모든 줄을 한꺼번에 읽을 떄는 readlines() 함수를 사용할 수 있다.
- readlines() 함수는 기본적으로 각 줄을 그대로 읽기 때문에 줄바꿈 기호(\n)가 포함된다.
- 줄바꿈 기호를 제거하기 위해 strip()을 사용할 수 있다.
- strip() 함수를 사용하지 않으면, 두 줄씩 줄바꿈이 수행된다.
[Input]
# f를 data.txt파일로 열고 내용 입력
f = open("data.txt", 'w')
f.write("안녕하세요.\n")
f.write("반갑습니다.\n")
f.write("행복하세요~!\n")
f.close()
f = open("data.txt", "r")
lines = f.readlines()
for i in range(len(lines)):
line = lines[i].strip()
print(f"{i}번째 줄의 내용: {line}")
f.close()
[Output]
0번째 줄의 내용: 안녕하세요.
1번째 줄의 내용: 반갑습니다.
2번째 줄의 내용: 행복하세요~!
- read() 함수를 사용하면 파일의 전체 내용을 하나의 문자열로 반환한다.
[Input]
f = open("data.txt", 'r')
data = f.read()
print(data)
f.close()
[Output]
안녕하세요.
반갑습니다.
행복하세요~!
파일 객체 자동으로 열고 닫기, open(), close() 함수
- 다음의 문법을 활용하여 파일 객체를 자동으로 여닫을 수 있다.
- open(), close() 함수의 기능이 함께 사용된다.
with open(파일 이름, 파일 열기 모드)as f:
파일 객체 f를 이용하는 코드
file_name = "output.txt"
with open(file_name, 'w') as f:
f.write("Hello World")
2. 함수의 이해와 활용
Definition
- 전체 소스코드를 기능별로 분리하여 작성하는 것이 효율적
- 함수를 이영해 소스 코드를 기능별로 분리할 수 있음
- def문을 사용
def add(a,b,c):
result = a + b + c
return result
print(add(3,1,5))
-> 9
Example 1) MaxIndex
- 리스트 내 원소 중에서 가장 큰 값의 인덱스를 리턴 ```python def find_max_index(arr): max_index = 0 for i in range(len(arr)): if arr[max_index]<arr[i]: max_index = i return max_index
data = [7,1,5,9,3,2,4] max_index = find_max_index(data) print(max_index) -> 3
### Example 2) find_certain_value
- 특정한 값을 가지는 원소의 인덱스를 찾는 함수
```python
def find_certain_value:
for i,x in enumerate(arr):
if x == value:
return i
return -1 # 찾지 못한 경우 -1을 리턴
print(find_certain_value([3,5,7,9]),2)
-> -1
print(find_certain_value([3,5,7,9]),7)
-> 2
Example 3) is_prime_number
def is_prime_number(x):
# 1이하인 경우 소수가 아님
if x<=1:
return False
# 1과 자기 자신 외의 자연수로 나누어 떨어지는 경우 소수가 아님
for divisor in range(2,x):
if x % divisor == 0:
return False
return True
print(is_prime_number(1)) # False
print(is_prime_number(2)) # True
print(is_prime_number(3)) # True
print(is_prime_number(4)) # False
print(is_prime_number(5)) # True
print(is_prime_number(7)) # True
print(is_prime_number(10)) # False
print(is_prime_number(13)) # True
print(is_prime_number(15)) # False
print(is_prime_number(17)) # True
3. 클래스의 이해와 활용
Definition
- 클래스는 딥러닝 프로그램 작성시 자주 사용됨
- 클래스: 붕어빵 틀에 비유할 수 있다.
- 인스턴스: 붕어빵 틀에서 생성된 붕어빵
Example 1) class Human
- 사람의 정보를 담는 클래스
- 프로그램 내에서 두 명의 사람을 처리한다면>
- 각 사람은 나이가 다를 수 있다.
class Human():
def __init__(self):
self.age = 0
def old(self):
self.age += 1
human1 = Human() # 사람 인스턴스 생성
human2 = Human() # 사람 인스턴스 생성
for i in range(10): # 10세
human1.old()
for i in range(20): # 20세
human2.old()
# 각 사람의 나이 출력
print(human1.old)
-> 10
print(human2.old)
-> 20
- 클래스(class)는 여러 정보를 하나의 객체에 담을 때 사용
Example 2) class Student
- 학생 관리 프로그램을 만들때, 학생에 대한 정보는 다양하다.
- 학번
- 이름
- 나이
- 성별
- 학과
- 학생 인스턴스를 생성함과 동시에 정보를 초기화할 수 있다.
- 생성자: 인스턴스가 생성될 때 자동으로 실행되는 init()매서드를 의미한다.
- self는 인스턴스(Instance) 자기 자신을 의미한다.
- 해당 인스턴스가 가지는 값과 함수의 인자 값을 구분하여 이해해야 한다.
- init() 함수 내부
- self.name: 현재 인스턴스의 name 변수
- name: 함수의 파라미터로 넘어 온 name 변수
[Input]
class Student:
def __init__(self, id, name, age, gender, department):
self.id = id
self.name = name
self.age = age
self.gender = gender
self.department = department
def show(self):
print("===== 학생 정보 =====")
print(f"학번: {self.id}")
print(f"이름: {self.name}")
print(f"나이: {self.age}")
print(f"성별: {self.gender}")
print(f"학과: {self.department}")
def add_age(self, offset):
self.age += offset
student1 = Student("20200001", "홍길동", 20, "남성", "컴퓨터공학과")
student2 = Student("20200002", "김순자", 21, "여성", "산업디자인공학과")
student3 = Student("20200003", "임꺽정", 23, "남성", "환경공학과")
student1.show()
student2.show()
student3.show()
[Output]
===== 학생 정보 =====
학번: 20200001
이름: 홍길동
나이: 20
성별: 남성
학과: 컴퓨터공학과
===== 학생 정보 =====
학번: 20200002
이름: 김순자
나이: 21
성별: 여성
학과: 산업디자인공학과
===== 학생 정보 =====
학번: 20200003
이름: 임꺽정
나이: 23
성별: 남성
학과: 환경공학과
self의 동작 방식
- 아래와 같이 클래스의 메서드를 호출
- 클래스의 메서드 호출
student1.add_age(5)
- 이때, student1 -> self에 대응되고, 값 5 -> offset에 대응된다.
- 클래스 메서드 구현
def add_age(self, offset):
self.age += offset
student1.add_age(5)
student1.show()
# 출력
===== 학생 정보 =====
학번: 20200001
이름: 홍길동
나이: 25
성별: 남성
학과: 컴퓨터공학과
Example 3) class Client
- 각 인스턴스의 인스턴스 변수는 서로 달다
- 특정한 클래스(class)의 모든 인스턴스끼 공유되는 정보가 필요하다면?
- 클래스 변수: 해당 클래스에서 전체적으로 공유되는 변수
- Client의 클래스 변수는 Client 클래스의 네임스페이스에 존재한다.
- 인스턴스 변수: 구체적인 하나의 인스턴스에서 사용되는 변수
- client1의 인스턴스 변수는 client1 인스턴스의 네임스페이스에 존재한다.
[Input]
class Client:
client_cnt = 0
def __init__(self, id, name, age, gender, point):
self.id = id
self.name = name
self.age = age
self.gender = gender
self.point = point
Client.client_cnt += 1
def show(self):
print("===== 고객 정보 =====")
print(f"고객 번호: {self.id}")
print(f"이름: {self.name}")
print(f"나이: {self.age}")
print(f"성별: {self.gender}")
print(f"고객 점수: {self.point}")
print(f"현재 총 고객 수: {Client.client_cnt}")
def __del__(self):
Client.client_cnt -= 1
client1 = Client(1, "홍길동", 20, "남성", 1200)
client2 = Client(2, "김순자", 21, "여성", 300)
client3 = Client(3, "임꺽정", 23, "남성", 700)
client1.show()
client2.show()
client3.show()
print(f"[결과] 현재 총 고객 수: {Client.client_cnt}")
[Output]
===== 고객 정보 =====
고객 번호: 1
이름: 홍길동
나이: 20
성별: 남성
고객 점수: 1200
현재 총 고객 수: 3
===== 고객 정보 =====
고객 번호: 2
이름: 김순자
나이: 21
성별: 여성
고객 점수: 300
현재 총 고객 수: 3
===== 고객 정보 =====
고객 번호: 3
이름: 임꺽정
나이: 23
성별: 남성
고객 점수: 700
현재 총 고객 수: 3
[결과] 현재 총 고객 수: 3
- 특정한 기준에 따라서 다수의 인스턴스를 정렬하고 싶을 때가 있다.
- 예를 들어 포인트 값이 큰 순서대로 정렬
- key 속성의 값으로 익명 함수를 넣을 수 있다.
- 이후에 뒤집기를 수행하면, point에 대하여 내림차순 정렬이 완료된다.
key = lambda x:x.point
- 또한 It 함수는 A가 B보다 작다는 의미를 정의할 때 사용한다. (less than)
- It 함수를 이용하여 정렬 기능을 구현할 수 있으며, 예시는 다음과 같다.
- 이후에 단순히 리스트에 대하여 sort() 함수를 적용하면, 정렬이 완료된다.
def __init__(self, other):
return self.point < other.point
[Input]
class Client:
def __init__(self, id, name, age, gender, point):
self.id = id
self.name = name
self.age = age
self.gender = gender
self.point = point
def show(self):
print("===== 고객 정보 =====")
print(f"고객 번호: {self.id}")
print(f"이름: {self.name}")
print(f"나이: {self.age}")
print(f"성별: {self.gender}")
print(f"고객 점수: {self.point}")
def __lt__(self, other):
return self.point < other.point
client1 = Client(1, "홍길동", 20, "남성", 1200)
client2 = Client(2, "김순자", 21, "여성", 300)
client3 = Client(3, "임꺽정", 23, "남성", 700)
client1.show()
client2.show()
client3.show()
[Output]
===== 고객 정보 =====
고객 번호: 1
이름: 홍길동
나이: 20
성별: 남성
고객 점수: 1200
===== 고객 정보 =====
고객 번호: 2
이름: 김순자
나이: 21
성별: 여성
고객 점수: 300
===== 고객 정보 =====
고객 번호: 3
이름: 임꺽정
나이: 23
성별: 남성
고객 점수: 700
- client를 리스트화 해서 저장
[Input]
client_list = [client1, client2, client3]
result = sorted(client_list, reverse=True)
for client in result:
client.show()
[Output]
===== 고객 정보 =====
고객 번호: 1
이름: 홍길동
나이: 20
성별: 남성
고객 점수: 1200
===== 고객 정보 =====
고객 번호: 3
이름: 임꺽정
나이: 23
성별: 남성
고객 점수: 700
===== 고객 정보 =====
고객 번호: 2
이름: 김순자
나이: 21
성별: 여성
고객 점수: 300
Class 상속(Inheritance)
- 클래스의 상속(inheritance)은 체계적인 프로그램 개발을 위해 필요하다.
- ex) 학교 관리 프로그램에서는 선생님(teacher)과 학생(student)에 대한 정보가 모두 활용된다.
- 이들은 공통적으로 이름(name), 나이(age) 등의 정보를 가지고 있다.
- 인적사항 정보를 출력하는 메서드를 둘 다 사용
- 상속을 사용하여 반복적으로 사용되는 변수 매번 선언 X
[Input]
class Human:
def __init__(self, name, age):
self.name = name
self.age = age
def show_student(self):
print("===== 학생 카드 =====")
print(f"학생 번호: {self.student_id}")
print(f"학년: {self.grade}")
print(f"점수: {self.score}")
student = Student("홍길동", 18, 1, 2, 95)
student.show_human()
student.show_student()
[Output]
===== 인적 사항 =====
이름: 홍길동
나이: 18
===== 학생 카드 =====
학생 번호: 1
학년: 2
점수: 95
- 실제로 딥러닝 분야에서 Pytorch 프레임워크를 사용할 때는 다양한 클래스를 상속 받아 사용할 수 있다.
- 다양한 기능이 라이브러리 형태로 제공되기 때문에, 상속을 받아 사용하는 것이 일반적이다.
- Generally 기본 라이브러리(부모 클래스) 직접 수정 X
- 상황에 맞게 적절히 상속받아 사용
4. 예외 처리
Definition
- 예외(exception)란, 코드 실행 도중에 발생하는 오류로 이해할 수 있다. 예를 들어 0으로 나누는 연산은 수행이 불가능하다.
- ZeroDivisionError: 0으로 나누었을 때 발생하는 오류
- 존재하지 않는 인덱스(Index) 접근 오류
try ~ except ~ 구문
- 특정한 오류를 처리
- 원하는 예외 이름에 대하여 처리
try ~ except ~ 구문
try: 기본적으로 실행할 코드 except: 예외가 발생했을 때 실행할 코드
Example 1) 존재하지 않는 인덱스에 접근
[Input]
list = [7,5,3]
index = 10
try:
data = list[index]
print(data)
except IndexError as e:
print("배열의 크기를 벗어난 인덱스에 접근할 수 없습니다")
print("[오류 메세지]")
print(e)
[Output]
배열의 크기를 벗어난 인덱스에 접근할 수 없습니다.
[오류 메시지]
list index out of range
Example 2) 0으로 나눌떄 오류
[Input]
data_list = [1, 2, 3, 4, 5]
index = 3
x = 0
try:
data = data_list[index]
result = data / x
print(result)
except IndexError as e:
print("배열의 크기를 벗어난 인덱스에 접근할 수 없습니다.")
print("[오류 메시지]")
print(e)
except ZeroDivisionError as e:
print("0으로 나눌 수 없습니다.")
print("[오류 메시지]")
print(e)
[Output]
0으로 나눌 수 없습니다.
[오류 메시지]
division by zero
- 딥러닝에서는 출력 차원이 일치하지 않아서 오류가 자주 발생
Reference
- 패스트 캠퍼스 강의 자료, 딥러닝을 위한 Python
- 모든 저작권은 패스트 캠퍼스에 있습니다.
댓글 남기기