C를 제외한 모든 프로그래밍 언어는 객체 지향 프로그래밍 언어이다. 객체 지향 프로그래밍이란 객체를 우선으로 생각해서 프로그래밍한다는 의미이다. 이 모든 프로그래밍 언어는 클래스 기반의 객체 지향 프로그래밍 언어이다. 클래스 기반의 객체 지향 프로그래밍 언어는 클래스라는 것을 기반으로 객체를 만들고, 그러한 객체를 우선으로 생각해서 프로그래밍하는 것을 이념으로 삼고 있다.
객체
프로그래밍 언어에서는 속성을 가질 수 있는 모든 것을 객체라고 부른다.
또한 프로그램에서 필요한 요소만을 사용해서 객체를 표현한 것을 추상화(abstraction)라고 부른다. 복잡한 자료, 모듈, 시스템 등으로 부터 핵심적인 개념 또는 기능을 간추려 내는 것을 추상화라고 한다. 자주 사용되는 용어이므로 꼭 기억하자!
▷ 딕셔너리로 객체 만들기
# 학생 리스트를 선언한다.
students = [
{"name":"윤인성", "korean":87, "english":88,"science":95},
{"name":"김남준", "korean":100, "english":99,"science":98},
{"name":"김태형", "korean":96, "english":94,"science":97},
{"name":"정호석", "korean":98, "english":90,"science":94},
{"name":"박지민", "korean":95, "english":90,"science":89},
{"name":"전정국", "korean":88, "english":82,"science":99},
]
# 학생을 한 명씩 반복한다.
print("이름","총점","평균", sep="\t")
for stdt in students:
#점수의 총합과 평균을 구한다.
score_sum = stdt["korean"]+stdt["english"]+stdt["science"]
score_avg = score_sum / 3
# 출력
print(stdt["name"], score_sum, score_avg, sep="\t")
|
[실행결과]
PS D:\app\python> python object_1_basic.py 이름 총점 평균 윤인성 270 90.0 김남준 297 99.0 김태형 287 95.66666666666667 정호석 282 94.0 박지민 274 91.33333333333333 전정국 269 89.66666666666667 PS D:\app\python> |
딕셔너리로 학생을 표현하고 이를 리스트로 묶어 학생들을 표현했다. 이처럼 여러 가지 속성을 가질 수 있는 대상을 객체라고 부르며, 현재 코드에서는 학생이 바로 객체이다.
그런데 딕셔너리로 객체를 하나하나 만드니 조금 복잡하고 귀찮다. 딕셔너리를 만들 때 키를 잘못 입력하는 실수가 일어날 가능성도 있다. 딕셔너리를 생성하는 코드를 아래와 같은 형태의 함수로 만들면 어떨까? 딕셔너리를 입력할 때보다 쉽고, 키를 잘못 입력하는 실수도 하지 않게 된다.
▷ 객체를 만드는 함수(1)
# 딕셔너리를 리턴하는 함수를 선언
def create_student(name, korean, engliish, science):
return{
"name":name,
"korean":korean,
"english":engliish,
"science":science
}
# 학생 리스트를 선언한다.
students = [
create_student("윤인성", 87, 88, 95),
create_student("김남준", 100, 99, 98),
create_student("김태형", 96, 94, 97),
create_student("정호석", 98, 90, 94),
create_student("박지민", 95, 90, 89),
create_student("전정국", 88, 82, 99)
]
# 학생을 한 명씩 반복한다.
print("이름","총점","평균", sep="\t")
for stdt in students:
#점수의 총합과 평균을 구한다.
score_sum = stdt["korean"]+stdt["english"]+stdt["science"]
score_avg = score_sum / 3
# 출력
print(stdt["name"], score_sum, score_avg, sep="\t")
|
[실행결과]
PS D:\app\python> python object_2_dict.py 이름 총점 평균 윤인성 270 90.0 김남준 297 99.0 김태형 287 95.66666666666667 정호석 282 94.0 박지민 274 91.33333333333333 전정국 269 89.66666666666667 PS D:\app\python> |
현재 총점과 평균을 구하는 처리를 학생을 대상으로만 이루어진다. 따라서 학생을 매개변수로 받는 형태의 함수로 만들면 코드가 조금 더 균형 잡히지 않을까?
▷ 객체를 처리하는 함수(2)
# 딕셔너리를 리턴하는 함수를 선언
def create_student(name, korean, engliish, science):
return{
"name":name,
"korean":korean,
"english":engliish,
"science":science
}
# 학생을 처리하는 함수를 선언
def student_get_sum(student):
return student["korean"]+student["english"]+student["science"]
def student_get_avg(student):
return student_get_sum(student) / 3
def student_to_string(student):
return "{}\t{}\t{}".format(
student["name"],
student_get_sum(student),
student_get_avg(student)
)
# 학생 리스트를 선언한다.
students = [
create_student("윤인성", 87, 88, 95),
create_student("김남준", 100, 99, 98),
create_student("김태형", 96, 94, 97),
create_student("정호석", 98, 90, 94),
create_student("박지민", 95, 90, 89),
create_student("전정국", 88, 82, 99)
]
# 학생을 한 명씩 반복한다.
print("이름","총점","평균", sep="\t")
for stdt in students:
# 출력
print(student_to_string(stdt))
|
[실행결과]
PS D:\app\python> python object_3_seperate.py 이름 총점 평균 윤인성 270 90.0 김남준 297 99.0 김태형 287 95.66666666666667 정호석 282 94.0 박지민 274 91.33333333333333 전정국 269 89.66666666666667 PS D:\app\python> |
실행결과는 이전과 같지만 이러한 형태로 객체와 관련된 코드를 분리할 수 있게 하는 것이 객체 지향 프로그래밍의 핵심이라고 할 수 있다. 그런데 이런 코드가 너무 자주 사용되다 보니, 개발자들은 클래스class라는 구조를 만들게 되었다. 클래스는 위와 같은 형태의 코드를 조금 더 효율적으로 만들기 위한 기능이라고 생각하면 된다.
클래스 선언하기
클래스는 객체를 조금 더 효율적으로 생성하기 위해서 만들어진 구문이다.
class 클래스 이름:
클래스 내용
이렇게 만들어진 클래스는 클래스 이름과 같은 함수(생성자)를 사용해서 객체를 만든다. 단순하게 생각하면 방금 전의 create_student() 함수와 같은 것이다.
인스턴스 이름(변수 이름) = 클래스 이름() #클래스 이름은 생성자 함수라고 부른다.
이러한 클래스를 기반으로 만들어진 객체를 인스턴스라고 부른다. 자주 사용되는 용어이므로 꼭 기억하자!
이를 기반으로 학생 6명을 선언한다면 다음과 같다.
# 클래스 선언
class Student:
pass
# 학생을 선언
student = Student()
# 학생 리스트를 선언
students = [
Student(),
Student(),
Student(),
Student(),
Student(),
Student()
]
|
생성자
클래스 이름과 같은 함수를 생성자(constructor)라고 부른다. 클래스 내부에 __init__라는 함수를 만들면 객체를 생성할 때 처리할 내용을 작성할 수 있다.
class 클래스 이름:
def __init__(self, 추가적인 매개변수):
pass
클래스 내부의 함수는 첫 번째 매개변수로 반드시 self를 입력해야 한다. 이때 self는 '자기 자신'을 나타내는 딕셔너리라고 생각하면 된다. 다만 self가 가지고 있는 속성과 기능에 접근할 때는 self.<식별자> 형태로 접근한다.
그럼 앞서 작성해본 create_student() 함수처럼 구현해 보자.
# 클래스 선언
class Student:
def __init__(self, name, korean, english, science):
self.name = name
self.korean = korean
self.english = english
self.science = science
# 학생 리스트를 선언
students = [
Student("윤인성", 87, 88, 95),
Student("김남준", 100, 99, 98),
Student("김태형", 96, 94, 97),
Student("정호석", 98, 90, 94),
Student("박지민", 95, 90, 89),
Student("전정국", 88, 82, 99)
]
# Student 인스턴스 속성에 접근하는 방법
students[0].name
students[0].korean
students[0].english
students[0].science
|
이렇게 만들면 Student 인스턴스가 생성될 때 속성이 직접 추가된다.
※ 소멸자
생성자와 반대로 인스턴스가 소멸될 때 호출되는 함수를 소멸자(destructor)라고 부른다. 많이 사용되는 기능은 아니지만, 소멸자는 클래스 내부에 __del__(self) 형태로 함수를 선언해서 만든다.
# 클래스 선언
class Test:
def __init__(self, name):
self.name = name
print("{} - 생성되었습니다".format(self.name))
def __del__(self):
print("{} - 파괴되었습니다".format(self.name))
test = Test("A")
|
[실행결과]
PS D:\app\python> python Test.py A - 생성되었습니다 A - 파괴되었습니다 |
생성자에 비해 소멸자가 호출되는 시점은 약간 복잡한데 <가비지 컬렉터>를 참고하면 된다.
메소드
클래스가 가지고 있는 함수를 메소드라고 부른다. 클래스 내부에 메소드를 만들 때는 다음과 같이 사용한다. 생성자를 선언하는 방법과 같다. 다만, 첫 번째 매개변수로 self를 넣어야 한다는 것을 다시 한번 기억하자.
class 클래스이름:
def 메소드이름(self, 추가적인 매개변수)
pass
※ 메소드와 함수
다른 언어는 메소드라는 용어를 많이 사용하지만 파이썬 언어는 멤버 함수(member function) 혹은 인스턴스 함수(instance function) 등의 용어를 더 많이 사용한다. 즉, 함수라는 용어를 주로 사용한다.
(object_3_seperate.py) 에서 만들었던 student_get_sum(), student_get_avg(), student_to_string() 함수를 클래스 내부에 구현해 보자. 이전의 매개변수로 student를 받았었는데, 이번에는 함수를 생성할 때 self를 입력한다.
▷ 클래스 내부에 함수(메소드) 선언하기
# 클래스를 선언
class Student:
def __init__(self, name, korean, engliish, science):
self.name = name
self.korean = korean
self.english = engliish
self.science = science
def get_sum(self):
return self.korean + self.english + self.science
def get_avg(self):
return self.get_sum() / 3
def to_string(self):
return "{}\t{}\t{}".format(
self.name,
self.get_sum(),
self.get_avg()
)
# 학생 리스트를 선언한다.
students = [
Student("윤인성", 87, 88, 95),
Student("김남준", 100, 99, 98),
Student("김태형", 96, 94, 97),
Student("정호석", 98, 90, 94),
Student("박지민", 95, 90, 89),
Student("전정국", 88, 82, 99)
]
# 학생을 한 명씩 반복한다.
print("이름","총점","평균", sep="\t")
for stdt in students:
# 출력
print(stdt.to_string())
|
[실행결과]
PS D:\app\python> python object_4_class.py 이름 총점 평균 윤인성 270 90.0 김남준 297 99.0 김태형 287 95.66666666666667 정호석 282 94.0 박지민 274 91.33333333333333 전정국 269 89.66666666666667 PS D:\app\python> |
(object_3_seperate.py) 에서는 student_to_string(stdt) 형태로 사용했지만, 이번에는 stdt.to_string() 형태로 사용했다.
연습문제
(연습문제 383p-2)
Q. 같은 객체라도 사용되는 프로그램에 따라서 속성이 달라질 수 있다. 예를 들어 가게 정보를 생각해 볼까? 음식 주문 어플리케이션에서 가게 정보를 저장한다면 가게 이름, 전화번호, 주소, 메뉴, 리뷰 목록 등을 저장할 것이다. 반면 세금 관리 어플리케이션에서 가게 정보를 저장한다면 메뉴 같은 것이 무엇이 있는지 저장할 필요가 없다. 대신 사업자등록증번호, 매출 상세 목록 등의 속성은 필요하다. 이와 같이 같은 객체라도 다른 속성을 갖게 되는 경우 두 종류 정보를 생각해 적어보자.
◇ 보험설계사정보 1) 보험사 영업수당 관리 앱 속성- 설계자사번, 설계사이름, 실적정보, 수당정보 2) 보험사 고객정보 고객번호, 고객이름, 가입상품정보, 담당설계사번호, 담당설계사이름 |
(연습문제 383p-3)
Q. 모든 객체에는 속성과 직접 행위가 따라온다. 예를 들어 주문 어플리케이션의 가게정보를 생각해 보자. '이 버튼을 누르면 전화가 걸리고, 이 버튼을 누르면 원하는 메뉴를 주문할 수 있고, 이 버튼을 누르면 리뷰 목록에 리뷰를 추가할 수 있으며, 이 버튼을 누르면 가게의 위치를 보여주는 등의 어떠한 자극에 대응되는 행위가 있다. 위에서 찾아본 객체 중 한 가지를 선택해 그 행의를 다섯 가지 생각해 적어보자.
◇ 보험사 영업수당 관리 앱 1) 설계사번호or 이름 검색 - 설계사사번, 설계사이름, 소속지점, 위/해촉 정보 확인 2) 실적정보 버튼 클릭 - 관련보험상품정보, 유지율 정보 3) 수당정보 버튼 클릭 - 수수료별 수당정보, 환수정보, 총 지급금액 정보 등. |
여기까지.
'개발자모드 > 혼자공부하는파이썬' 카테고리의 다른 글
다음 파이썬 공부는 [점프 투 장고]로 정했다. 웹 개발 Go! (0) | 2022.07.29 |
---|---|
[파이썬#24][고급] 클래스의 추가적인 구문 - isinstance(), 클래스 변수와 함수, 상속, 가비지컬렉터, 게터와 세터 ★혼공파 최종편★ (0) | 2022.07.28 |
[파이썬#22][고급] 모듈 만들기 (__name__활용, 패키지 생성, __init__.py파일, 인터넷 이미지 저장) (0) | 2022.07.25 |
[파이썬#21][고급] 외부 모듈 (모듈 설치 pip install, BeautifulSoup, Flask) (0) | 2022.07.22 |
[파이썬#20][고급] 표준 모듈 (math, random, sys, os, datetime, time, urllib) (0) | 2022.07.20 |
댓글