본문 바로가기
Programming/Python

21. 클래스

by IT learning 2021. 3. 26.
728x90

이번에는 클래스와 객체에 대해서 배워보겠다.

파이썬 이외에 내가 배운것은 C, C++, JAVA, 정도이다.

이 중에서 C 빼고는 모두 다 객체 지향 프로그래밍 언어 이다. (C는 절차 지향 프로그래밍 언어)

객체 지향 프로그래밍 언어란 객체를 우선으로 생각해서 프로그래밍한다는 의미이다.

 

클래스 기반의 객체 지향 프로그래밍 언어는 클래스라는 것을 기반으로 객체를 만들고,

그러한 객체를 우선으로 생각해서 프로그래밍 하는 것을 이념으로 삼고 있다.

 

객체

프로그램을 만들 때는 우선 '우리가 어떤 데이터를 활용하는가?'를 생각해야 한다.

예를 들어 병원에서 사용하는 업무 프로그램을 만든다면, 의사, 간호사, 환자, 병실, 예약 기록 등등과 같은 데이터를 먼저 고려한다.

 

추상화
프로그램에서 필요한 요소만 사용해서 객체를 표현하는 것을 추상화 라고 한다. 조금 더 포괄적인 사전적 의미로 말하자면 복잡한 자료, 모듈, 시스템 등으로부터 핵심적인 개념 또는 기능을 간추려 내는 것을 추상화라고 한다.

간단히 말하자면, 아이스크림을 예로 들겠다.
아이스크림이라고 해서 다 같은 아이스크림이 아니지 않은가?
바 형태의 아이스크림도 있을테고, 퍼먹는 아이스크림, 구슬 아이스크림 등등 형태가 다양하다.
이처럼 각 아이스크림에서 사용하는 방법들이 다른것을 따로 표현하는 방법을 추상화라고 한다.

 

만약 학생 성적 관리 프로그램을 만들려고 한다면 무엇이 필요할까?

학생 이름, 학번, 과목별 성적 등이 필요할테다.

students = [
    {"name": "ITlearn", "korean": 87, "math": 98, "english": 97, "science": 95 },
    {"name": "Kirri", "korean": 83, "math": 68, "english": 87, "science": 96 },
    {"name": "Penguin", "korean": 87, "math": 86, "english": 98, "science": 100 },
    {"name": "Lion", "korean": 86, "math": 96, "english": 96, "science": 95 }
]

# 학생을 한 명씩 반복합니다.
print("이름", "총점", "평균", sep="\t")

for student in students:
    # 점수의 종합과 평균을 구합니다.
    score_sum = student["korean"] + student["math"] + student["english"] + student["science"]
    score_average = score_sum / 4
    print(student["name"], score_sum, score_average, sep="\t")

위 코드를 살펴보자.

딕셔너리로 학생을 표현하고 이를 리스트로 묶어 학생들을 표현했다.

이처럼 여러가지 속성을 가질 수 있는 대상을 객체(Object)라고 부른다.

위 코드의 실행결과이다.

현재 코드에서는 학생이 바로 객체이다.

 

그런데 딕셔너리로 객체를 하나하나 만드니 조금 귀찮다. 딕셔너리를 만들 때 키를 잘못 입력하는 실수도 생길 수 있다.

그럼 이렇게 만들면 어떨까?

def create_student(name, korean, math, english, science):
    return {
        "name": name,
        "korean": korean,
        "math": math,
        "english": english,
        "science": science
    }

# 학생 리스트를 선언
students = [
    create_student("ITlearn", 87, 98, 97, 85),
    create_student("Kirri", 82, 83, 84, 85),
    create_student("Penguin", 95, 97, 96, 94),
    create_student("Lion", 86, 87, 94, 95)
]

print("이름", "총점", "평균", sep="\t")
for student in students:
    score_sum = student["korean"] + student["math"] + student["english"] + student["science"]
    score_average = score_sum / 4
    print(student["name"], score_sum, score_average, sep="\t")

위 코드를 살펴보자.

실행결과는 이전과 같다.

뭔가 이전 코드보다는 정리가 된 듯한 느낌이다.

 

하지만, 지금 코드의 현재 총점과 평균을 구하는 처리는 학생을 대상으로만 이루어진다.

그렇다면 이렇게 바꾸면 어떨까?

def create_strdent(name, korean, math, english, science):
    return {
        "name": name,
        "korean": korean,
        "math": math,
        "english": english,
        "science": science
    }

# 학생을 처리하는 함수를 선언합니다.
def student_get_sum(student):
    return student["korean"] + student["math"] + student["english"] + student["science"]

def student_get_average(student):
    return student_get_sum(student) / 4

def student_to_string(student):
    return "{}\t{}\t{}".format(student["name"], student_get_sum(student), student_get_average(student))

# 학생 리스트를 선언합니다.

students = [
    create_strdent("1", 45, 65, 45, 78),
    create_strdent("2", 98, 98, 97, 94),
    create_strdent("3", 85, 94, 97, 64),
    create_strdent("4", 45, 87, 88, 98)
]

# 학생을 한 명씩 반복합니다.
print("이름", "총점", "평균", sep="\t")
for student in students:
    print(student_to_string(student))

위 코드를 살펴보자.

실행결과는 이전과 같지만 코드가 점점 분리가 되고 있다.

학생이라는 객체와 관련된 기능이 위로 올라갔고, 학생들을 처리하는 함수들은 아래로 내려갔다.

이렇게 만들면 '학생 객체와 관련된 기능'을 별도의 모듈로 빼서 관리할 수도 있다.

 

이러한 형태로 객체와 관련된 코드를 분리할 수 있게 하는 것이 객체 지향 프로그래밍의 핵심이다.

 

그리고 이런 방법을 많이 쓰다 보니, 클래스라는 구조를 만들어 더 편하게 사용하게 되었다.

 

클래스 선언하기

클래스는 객체를 조금 더 효율적으로 생성하기 위해서 만들어진 구문이다.

class 클래스 이름:
	클래스 내용

클래스는 이렇게 사용한다.

글래스의 이름은 보통 첫자를 대문자로 시작하는 단어로 생성해야 한다.

대문자로 시작하지 않아도 생성은 되지만, 많은 파이썬 개발자들이 이러한 규칙을 준수하고 있기 때문에 지키는게 좋다.

 

이렇게 만들어진 클래스 이름과 같은 함수(생성자)를 사용해서 객체를 만든다.

단순하게 생각하면 이전의 create_student() 함수와 같은 것이다.

 

이러한 클래스를 기반으로 만들어진 객체를 인스턴스라고 한다.

 

생성자

클래스 이름과 같은 함수를 생성자라고 부른다.

클래스 내부에 __init__ 라는 함수를 만들면 객체를 생성할 때 처리할 내용을 작성 할 수 있다.

 

클래스 내부의 함수는 첫 번째 매개변수로 반드시 self 를 입력해야 한다. self는 자기 자신을 나타내는 딕셔너리라고 생각하자.

(C++ 에서 this를사용하는것과 같은느낌이다.)

 

메소드

클래스가 가지고 있는 함수를 메소드라고 한다.

클래스 내부에 메소드를 만들 때는 다음과 같이 사용한다.

class 클래스 이름:
	def 메소드 이름(self, 추가적인 매개변수):
    	pass

아까 만들었던 학생 관리 프로그램을 메소드를 사용해 만들어보자.

# 클래스 내부에 함수(메소드) 선언하기
class Student:
    def __init__(self, name, korean, math, english, science):
        self.name = name
        self.korean = korean
        self.math = math
        self.english = english
        self.science = science

    def get_sum(self):
        return self.korean + self.math + self.english + self.science

    def get_average(self):
        return self.get_sum() / 4

    def to_string(self):
        return "{}\t{}\t{}".format(
            self.name,
            self.get_sum(),
            self.get_average())
    
students = [
    Student("1", 45, 65, 45, 78),
    Student("2", 46, 78, 87, 97),
    Student("3", 46, 78, 76, 97),
    Student("4", 87, 78, 87, 97),
]

print("이름", "총점", "평균", sep="\t")
for student in students:
    print(student.to_string())

위 코드의 실행결과이다.

이렇게 따로 놀았던 함수들을 클래스로 모아 사용하는 방법을 배울 수 있었다.

 

정리
객체
는 속성을 가질 수 있는 모든 것을 의미한다.
객체 지향 프로그래밍 언어는 객체를 기반으로 프로그램을 만드는 프로그래밍 언어를 의미한다.
추상화는 복잡한 자료, 모듈, 시스템 등으로부터 핵심적인 개념 또는 기능을 간추려 내는 것을 의미한다.
클래스는 객체를 쉽고 편리하게 생성하기 위해 만들어진 구문이다.
인스턴스는 클래스를 기반으로 생성한 객체를 의미한다.
생성자는 클래스 이름과 같은 인스턴스를생성할 때 사용하는 함수이다.
메소드는 클래스가 가진 함수를 의미한다.
728x90

'Programming > Python' 카테고리의 다른 글

23. 가비지 컬렉터(Garbage Collector)  (0) 2021.03.28
22. 클래스의 추가적인 구문  (0) 2021.03.27
20. 모듈 만들기  (0) 2021.03.25
19. 외부 모듈(Beautiful Soup, Flask 모듈)  (0) 2021.03.24
18. 표준 모듈  (0) 2021.03.23

댓글

IT_learning's Commit