본문 바로가기
#단편모음/낱 장

[혼공파] C08 클래스-230608木

by taeni 2024. 4. 16.

 

C08 클래스

08-1 클래스의 기본

08-2 클래스의 추가적인 구문


08-1 클래스의 기본       (p.382 마무리)

객체object는 속성을 가질 수 있는 모든 것을 의미합니다.

객체 지향 프로그래밍 언어Object Oriented Programming Language는 객체를 기반으로 프로그램을 만드는 프로그래밍 언어를 의미합니다.

추상화abstraction는 복잡한 자료, 모듈, 시스템 등으로부터 핵심적인 개념 또는 기능을 간추려 내는 것을 의미합니다.

클래스class는 객체를 쉽고 편리하게 생성하기 위해 만들어진 구문입니다.

인스턴스Instance는 클래스를 기반으로 생성한 객체를 의미합니다.

생성자construnctor는 클래스 이름과 같은 인스턴스를 생성할 때 사용하는 함수입니다.

메소드method는 클래스가 가진 함수를 의미합니다.

 

08-2 클래스의 추가적인 구문   (p.411 마무리)

isinstance() 함수는 어떤 클래스의 인스턴스인지 확인할 때 사용하는 함수입니다.

클래스변수 클래스 함수는 클래스 이름 뒤에, (마침표)를 찍고 바로 사용할 수 있는 클래스가 갖고 있는 변수와 함수입니다.

상속은 어떤 클래스를 기반으로 그 속성과 기능을 물려받아 새로운 클래스를 만드는 것을 말합니다.


08-1 클래스의 기본

객체 지향 언어 (OOP;Object Oriented Programming)Language 이란 객체를 우선으로 생각해서 프로그래밍한다는 의미이다.

객체지향언어의 큰 특징은 : 클래스Class를 기반으로 객체Object를 만들고, 그러한 객체를 우선으로 생각해서 프로그래밍하는 것을 이념으로 삼는 것이다.

추상화Abstraction : 공통의 속성이나 기능을 묶어 이름을 붙이는 것.

 

프로그래밍을 만들 떄는 우선 '우리가 어떤 데이터를 활용하는가?'를 생각하게 됩니다. 병원에서 사용하는 업무 프로그램을 만든다면, 의사, 간호사, 환자, 병실, 예약 기록, 진료 기록, 입퇴원 기록과 같은 데이터data를 먼저 고려해야 한다.

 

객체

학생 성적 관리 프로그램을 만든다면 무엇이 필요할까? 학생 이름, 학번, 과목별 성적 등이 필요한다.

다음과 같이 이를 리스트와 딕셔너리로 표현해보았다.

해설
1️⃣딕셔너리로 학생을 표현하고, 이를 리스트로 묶어 학생들을 표현했다.
이처럼 여러 가지 속성을 가질 수 있는 대상을 객체Object라고 부른다.

위의 코드(맨위의 왼쪽 코드)에서는 학생이 바로 객체이다.

프로그래밍 언어에서는 속성을 가질 수 있는 모든 것을 '객체'라고 부른다.
사실 위의 예제에서 리스트로 선언한 'students', 즉 '학생들'도 '여러 학생'이라는 일종의 속성을 가지고 있는 것이다. 
그래서 이것도 '객체'라고 부를 수 있다.
2️⃣그런데 딕셔너리로 객체를 하나하나 만드니 조금 복잡하고 귀찮다. 딕셔너리를 만들 때 키를 잘못 입력하는 실수 가 일어날 가능성도 있다.

따라서 
딕서너리를 생성하는 코드(맨위의 오른쪽 코드)처럼
함수로 만들면 어떨까?

함수로 만들게 되면 딕셔너리를 입력할 때보다 쉽고, 키를 잘못 입력하는 실수도 하지 않게 된다.

3️⃣조금 더 생각해 볼까?

현재 총점과 평균을 구하는 처리는 학생을 대상으로만 이루어진다
따라서 학생을 매개변수로 받는 형태의 함수로 만들면 코드가 조금 더 균형잡히지 않을까?

실행결과는 이전과 같지만 코드가 조금씩 분리되고 있다. 학생이라는 객체와 관련된 기능이 위로 올라갔고, 이러한 객체를 사용하는 처리가 아래로 내려갔다. 이렇게 만들면 '학생 객체와 관련된 기능' 별도의 모듈로 빼서 관리할 수도 있다.

이러한 형태로 객체와 관려된 코드를 분리할 수 있게 하는 것이 객체 지향 프로그래밍의 핵심이라고 할 수 있다. 그런데 이런 크도가 너무 자주 사용되다 보니, 개발자들은 클래스Class라는 구조를 만들게 되었다.

클래스 선언하기

클래스는 객체를 조금 더 효율적으로 생성하기 위해서 만들어진 구문이다. 일단 클래스의 기본적인 구문을 살펴보고 무엇이 효율적인지 알아보도록 하자.

 

클래스는 다음과 같은 구문으로 생성한다.

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

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

위의 코드 중 create_student()함수와 같은 것이다.

인스턴스 이름(변수 이름) = 클래스 이름()    #👉생성자 함수라고 부른다.

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

 

例)

이를 기반으로 학생 6명을 선언한다면 다음과 같다.

#클래스를 선언합니다.
class Student:
pass

#학생을 선언합니다.
student = Student()

#학생 리스트를 선언합니다.
student = [
    Student(),
    Student(),
    Student(),
    Student(),
    Student()  
]

생성자

클래스 이름과 같은 함수를 생성자Constructor라고 부른다. 클래스 내부에 _ _init_ _라는 함수를 만들면 객체를 생성할 때 처리할 내용을 작성할 수 있다.

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

클래스 내부의 함수는 첫 번째 매개변수로 반드시 self를 입력해야 한다. 이때 self는 '자기 자신'을 나타내는 딕셔너리라고 생각하면 된다. 다만 self가 가지고 있는 속성과 기능에 접근 할 때는 self.<식별자> 형태로 접근한다.

tip
self 키워드가 아니라 단순한 식별자이므로, 변수 이름으로 활용해도 된다. 
하지만 거의 모든 파이썬 개발자가 self라는 이름을 사용하고 있으므로 기본 규칙을 지키는 것이 좋겠다!

메소드

클래스가 가지고 있는 함수를 메소드method라고 부른다. 클래스 내부에 메소드를 만들 때는 다음과 같이 사용한다. 생성자를 선언하는 방법과 같다. 다만, 첫 번째 매개변수로 self를 넣어야 한다는 것을 다시 한 번 기억하자.

cf. 언어와 용어 (약간 차이)
메소드와 함수 C#, Java 등의 프로그래밍 언어는 클래스의 함수를 '메소드'라고 부를 정도로 메소드라는 용어를 많이 사용한다.
하지만 파이썬 프로그램이 언어는 멤버 함수(member function) 혹은 인스턴스 함수(instance function) 등의 용어를 더 많이 사용한다. 
이 책에서도 함수(function)라는 용어를 주로 사용한다.

374쪽(위의 객체3️⃣코드)에서 만들었던 student_get_sum(), student_get_average(), student_to_string() 함수를 클래스 내부에 구현해보도록 하자. 이전에는 매개변수로 student를 받았었는데, 이번에는 함수를 생성할 때 self 를 입력한다.

지금까지 딕셔너리와 함수를 조합해서 만들었던 학생 객체를 👉 클래스로 만들어보았다.

 

374쪽의 객체3️⃣코드에서는 student_to_string(student) 형태로 사용했지만, 이번에는 student.to_string()형태로 사용했다. 어떠한 객체가 가지고 있는 어떠한 함수(기능)을 명확하게 이해할 수 있으므로 편리하다고 할 수 있다.


확인문제1

여러 가지 프로그램에 들어 있는 객체를 생각해보자. 예를 들어 페이스북이라면 개인 정보, 타임라인 글, 그룹 정보 등을 생각해 볼 수 있다. 개인 정보라면 이름, 이메일, 비밀번호, 프로필 사진, 프로필 설명, 친구 목록, 타임랑니 글 목록 등을 생각해 볼 수 있다. 타임라인 글이라면 작성자, 게시 시간, 좋아요 수, 좋아요를 남긴 친구, 댓글 등을 생각 해 볼 수 있다.

프로그램 객체 속성
페이스북 개인 정보 이름, 이메일, 비밀번호, 프로필 사진, 프로필 설명, 친구 목록, 타임라인 글 목록...etc
타임라인 글 작성자, 게시 시간, 좋아요를 누른 친구, 댓글...etc
그룹 정보 이름, 설명, 멤버 목록...etc

08-2 클래스의 추가적인 구문

클래스를 사용하는 것은 작정하고 속성과 기능을 가진 객체를 만들겠다는 의미입니다. 그래서 파이썬은 그에 따른 부가적인 기능을 지원합니다. 예를 들어

  • 어떤 클래스를 기반으로 그 속성과 기능을 물려받아 새로운 클래스를 만드는 상속, 
  • 이러한 상속 관계에 따라서 객체가 어떤 클래스를 기반으로 만들었는지 확인할 수있게 해주는 isinstance() 함수,
  • 파이썬이 기본적으로 제공하는 str()함수 혹은 연산자를 사용해서 클래스의 특정 함수를 호출할 수 있게 해주는 기능

등이 대표적인 예입니다.

 

어떤 클래스의 인스턴스인지 확인하기

일단 객체(인스턴스)가 어떤 클래스로부터 만들어졌는지 확인할 수 있도록 isinstance()함수를 제공합니다.

isinstance()함수는 첫 번째 매개변수에 객체(인스턴스), 두 번째 매개변수에 클래스를 입력합니다.

isinstance(인스턴스, 클래스)

# 클래스를 선언합니다.
class Student:
	def __init__(self):
    	pass
# 학생을 선언합니다.
student = Student()
# 인스턴스 확인하기
print("isinstnace(student, Student):", isinstance(student, Student))

isinstance() vs type()
isinstance() : 상속 관계까지 확인 type() : 상속 관계 확인X

일반적으로 객체 지향 프로그래밍은 모든 데이터를 클래스로 구현한다. 이러한 데이터를 관리할 때 종류별로 리스트를 따로 만들고 활용해야 한다고 생가하는 경우가 많은데, isinstance()함수를 사용하면 이처럼 하나의 리스트로도 여러 종류의 데이터를 다룰 수 있다.


특수한 이름의 메소드

_ _<이름>_ _()

위 형태의 메소드 : 파이썬이 클래슬르 사용할 때 제공해 주는 보조 기능으로, 특수한 상황에 자동오르 호출되도록 만들어졌다.

크기 비교 함수
이름 영어 설명
eq equal 같다
ne not equal 다르다
gt  greater than 크다
ge greater than or equal 크거나 같다
lt less than 작다
le less than or equal 작거나 같다

이를 활용해서 학생들을 성적으로 비교하는 기능을 만들어 보자.

 

 

클래스 변수와 메소드

인스턴스가 속성과 기능을 가질 수도 있지만, 클래스가 속성(변수)과 기능(함수)을 가질 수도 있다.

클래스 변수는 class 구문 바로 아래의 단계에 변수를 선언하기만 하면 된다. 이렇게 만들어진 클래스 변수는 다음과 같이 사용된다.

# 클래스 변수 만들기
class 클래스 이름:
	클래스 변수 = 값
    
# 클래스 변수에 접근하기
클래스 이름.변수 이름

 

 

 

 

(왼쪽 사진 설명)

- 학생의 수를 세는 Student.count라는 변수를 만들고 활용

사실 일반적인 변수로 만드나 클래스 변수로 만드나 사용에는 큰 차이가 없다.

 

- 하지만 '클래스가 가진 기능'을 명시적으로 나타내서 변수를 만든다는 것이 포인트라고 할 수 있다.

 

에러사항 기록) 파이썬에서 뜻모를 nameerror가 발생했다면 들여쓰기를 다시 한번 고쳐보도록 하자!

 

 

 

 

 

 

 

클래스 함수

클래스 함수도 클래스 변수처럼 그냥 클래스가 가진 함수이다. 일반적인 함수로 만드나 클래스 함수로 만드나 사용에는 큰 차이가 없다. 다만 '클래스가 가진 기능'이라고 명시적으로 나타내는 것 뿐이다.

그런데 생성하는 방법이 조금 특이하다. @classmethod 부분을 데코레이터decorator라고 부른다.

@ 로 시작하는 것 : "데코레이터" , (means)꾸며주는 것
데코레이터를 만드는 방법에 따라 2分
① 함수 데코레이터
② 클래스 데코레이터
+ 다른 프로그램이 언어에서는 @라는 기호를 어노테이션(annotation)으로 사용하기에 혼동 될 수 있으므로 유의
  (기능이 크게 다르다)

클래스 함수 만들기

class 클래스 이름:
	@classmethod
	def 클래스 함수(cls, 매개변수):
	pass

클래스 함수의 첫 번째 매개변수에는 클래스 자체가 들어온다. 일반적으로 cls(그냥 '클래스'라고 읽으면 된다.)이름의 변수로 선언하며, 이렇게 만들어진 클래스 함수는 다음과 같이 사용한다.

# 클래스 함수 호출하기
 클래스 이름.함수 이름(매개변수)

● 좀 더 알아보기 ① 가비지 컬렉터

파이썬으로 프로그래밍을 할 때는 프로그래밍 언어의 내부에서 일어나는 일을 크게 신경 쓰지 않아도 프로그램을 만들 수 있다.(C, C++ 프로그래밍 언어 등은 내부에서 일어나는 일을 이해해야 한다.)
그래도 이정도는 알아야 하는 알아야 하는 개념이 있다면 '가비지 컬렉터'이다.


<가비지 컬렉터 garbage collector>


프로그램 내부에서 무언가를 생성한다는 것은 = 메모리 위에 올린다는 의미
참고로 메모리가 부족해지면 컴퓨터는 하드디스크를 메모리처럼 사용해 무언가를 올리기 시작한다. 
ㄴ 이러한 동작을 스왑swap이라고 하는데, 하드디스크는 메모리보다 훨씬 느리므로 스왑을 처리하는 속도도 느리다.

어쨌든 프로그램에서 변수를 만들면 데이터가 메모리에 올라가고, 계속 만들다 보면 메모리가 가득 차버릴 것이다. 👉이를 방지하기 위해 파이썬 프로그래밍 언어에는 '가비지 컬렉터'라는 것이 있다. 가비지 컬렉터는 더 사용할 가능성이 없는 데이터를 메모리에서 제거하는 역할을 한다.

그럼 '더 사용할 가능성이 없는 데이터'라는 것은 무엇일까? 여러 경우 수가 있지만, 가장 대표적인 경우는 변수에 저장되지 않거나, 함수 등에서 나오면서 변수를 활용할 수 없게 되는 경우라고 할 수 있다.

● 좀 더 알아보기 ② 프라이빗 변수와 게터/세터

객체 지향 프로그래밍의 최종 목표는 : 객체를 효율적으로 만들고 사용하는 것이다.

객체를 효율적으로 사용하기 위한 추가 기능을 알아보기 위해 간단한 예를 살펴보자.

프라이빗 변수

일단 변수를 마음대로 사용하는 것을 막아야 한다. 파이썬은 클래스 내부의 변수를 외부에서 사용하는 것을 막고 싶을 때 인스턴스 변수 이름을 _ _<변수 이름> 형태로 선언한다. 

게터와 세터

그런데 중간에 원의 둘레를 변경하고 싶다면 어떻게 해야 할까? 클래스 외부에서 직접 _ _radius속성에 접근할 수 없기 떄문에 간접적으로 접근할 수있는 방법을 찾아야 한다.

 

이때 사용되는 것이 게터getter와 세터setter이다. 게터와 세터는 프라이빗 변수의 값을 추출하거나 변경할 목적으로, 간접적으로 속성에 접근하도록 해주는 함수이다.

(위 사진) get_radius()함수와 set_radius()함수를 만들어서 함수로 프라입시 변수의 값에 접근하거나, 값을 변경하게 했다.
이렇게 함수를 사용해 값을 변경하면 여러 가지 처리를 추가할 수 있다.
예를 들어 set_radius()함수에 다음과 같은 코드를 추가하면 _ _radius에 할당할 값을 양의 숫자로만 한정할 수 있다.

# 게터 세터로 변수를 안전하게 사용하기
def set_radius(self, value):
	if value <= 0:
    	raise TypeError("길이는 양의 숫자여야 합니다.")
    self.__radius = value

 

데코레이터를 사용한 게터와 세터

그런데 중간에 게터와 세터를 함수로 만드는 일이 많아져서 파이썬 프로그래밍 언어는 게터와 세터를 쉽게 만들고 사용할 수 있게 하는 기능을 제공한다.

다음과 같이 변수 이름과 같은 함수를 정의하고 위에 @property와 @<변수 이름>.setter라는 데코레이터를 붙여 준다.

이렇게 하면 circle.radius를 사용하는 것만으로도 자동으로 게터오 세터가 호출되도록 할 수 있다.

지금까지 계속 언급했던 것처럼 기존의 사용 방법과 같은 방법으로 객체를 사용할 수 있다.

 

● 좀 더 알아보기 ③ 상속

후클래스 기반의 객체 지향 언어들은 상속inheritance이라는 기능을 지원한다.

 

상속

다른 누군가가 만들어 놓은 기본 형태에 내가 원하는 것만 교체하는 것.

기반이 되는 것을 부모parent라고 부르고, 이를 기반으로 생성한 것을 자식child라고 부른다.

부모가 자식에게 자신의 기반을 물려주느 기능이므로 '상속'이라고 부른다.

 

다중 상속

혹은 다른 누군가가 만들어 놓은 형태들을 조립해서 내가 원하는 것을 만드는 것도 '상속'이다. ☞ 이를 '다중 상속'이라고 부른다.

예외 클래스 만들기

상속은 기존에 있는 클래스를 기바능로 조금 수정해서 내가 원하는 클래스를 만들 때 사용한다. 그럼 Exception이라는 기존에 있는 클래스를 조금 수정해서 CustomException이라는 클래스를 만들어 보자.

저자는 처음 공부할 때 상속을 왜 사용하는지 아무리 책을 읽어도 이해할 수 없어서 상속이라는 개념을 아예 잊고 살다가.  어느 날 아무 생각 없이 외워서 쓰고 있던 코드가 상속을 사용하는 코드라는 것을 느낀 후 그때부터 다시 상속과 관련되 내용을 공부하고 상속을 이해하게 되었다고 한다.

 

현재 단계에서 너무 이해하는 것이 어렵다면, 나중에 관련된 코드가 나왔을 때 상속을 사용했다는 것을 인지할정도로 기억해보도록 하자.

 

이제 이 책으로 기본편, 고급편을 모두 완료하였다.

파이썬 기초 문법을 배운 것에서 한 단계 더 나아가고 싶다면 

웹 서비스 개발, 인공지능 개발, 데이터 수집 프로그램 개발, 데이터 분석, 업무 자동화 등을 공부해보자.

혹은 파이썬으로 프로그래밍 언어의 기본을 확실하게 다졌다고 생각된다면 다른 프로그래밍 언어로 넘어가는 것도 고려해보자.

 

 

혼자 공부하는 파이썬 1독 완료!!

'#단편모음 > 낱 장' 카테고리의 다른 글

[혼공파] C07 함수-230601木  (0) 2024.04.16
[혼공파] C06 예외처리-230521日  (0) 2024.04.16
[혼공파] C05 함수-230516火  (0) 2024.04.16
[혼공파] C04 반복문-230515月  (0) 2024.04.16
[혼공파] C03 조건문-230512金  (0) 2024.04.16