📗 Docs

[python] 클래스(Class)의 이해와 활용

date
Jul 10, 2023
slug
python-grammar-class
author
status
Public
tags
Python
Rest
summary
type
Post
thumbnail
category
📗 Docs
updatedAt
Aug 26, 2024 03:58 PM

1) 활용

클래스(Class)는 객체 지향 프로그래밍을 가능하도록 해주는 기본적인 단위이다. 클래스는 함수(function)처럼 불필요한 소스코드를 최소화 하면서 현실 세계의 사물을 컴퓨터 프로그래밍 상에서 쉽게 표현할 수 있도록 해주는 프로그래밍 기술이다.
 
클래스를 이용해 현실 세계의 사물의 특성을 정의할 수 있다. 예를 들어 ‘자동차’라는 것을 정의했다면 하면, 이를 실제로 프로그램 상에서 인스턴스(instance)로 만들어서 사용할 수 있다. 예를 들어 ‘빨간 자동차’, ‘파란 자동차’ 등의 구체적인 인스턴스로 만드는 것이 가능하다.
 
클래스 요소(2가지)
  1. 클래스의 멤버 : 클래스 내부에 포함되는 변수
  1. 클래스의 함수 : 클래스 내부에 포함되는 함수, 메소드라고도 함.
 
  • 생성자 : __init__()함수를 사용할 수 있다. 이는 개별 인스턴스의 구체적인 멤버 변수를 설정할 수 있도록 해줌.
class Car: # 클래스의 생성자 def __init__(self, name, color): self.name = name # 클래스의 멤버 self.color = color #클래스의 멤버 # 클래스의 메소드 def show_info(self): print("이름:", self.name, "/ 색상:", self.color) car1 = Car("소나타", "빨간색") car1.show_info()
 
  • 클래스의 메소드 : 클래스는 메소드를 이용해 다양한 처리가 가능함. 이때 메소드는 첫 번째 매개변수는 반드시 self가 되어야 함. self의 의미는 클래스를 이용해 생성된 인스턴스 그 자체를 의미함. 일반적으로 멤버 변수의 값을 바꾸는 함수를 setter메소드라고 부름.
class Car: # 클래스의 생성자 def __init__(self, name, color): self.name = name # 클래스의 멤버 self.color = color #클래스의 멤버 # 클래스의 메소드 def show_info(self): print("이름:", self.name, "/ 색상:", self.color) # setter 메소드 def set_name(self, name): self.name = name car1 = Car("소나타", "빨간색") car1.ser_name("제네시스") car1.show_info()
 
  • 클래스의 소멸자 : 클래스의 소멸자는 생성자와는 반대로 메모리에서 할당 해제될 때 실행되는 함수
class Car: # 클래스의 생성자 def __init__(self, name, color): self.name = name # 클래스의 멤버 self.color = color #클래스의 멤버 # 클래스의 소멸자 def __del__(self): print("인스턴스를 소멸시킵니다.") #클래스의 메소드 def show_info(self): print("이름:", self.name, "/ 색상:", self.color) # setter 메소드 def set_name(self, name): self.name = name car1 = Car("소나타", "빨간색") car1.ser_name("제네시스") car1.show_info() de1 car1
 
  • 클래스의 상속 : 클래스는 객체 지향 프로그래밍의 특성인 ‘상속’을 가능하도록 해줌. 특정한 하나의 클래스는 ‘상속’을 이용해 다른 클래스의 멤버 변수와 메소드를 물려받아 사용할 수 있음. 상속을 할 때는 클래스를 정의할 때 소괄호()를 이용하여 상속 받을 클래스를 적을 수 있음.
class Unit: def __init__(self, name, powe): self.name = name self.power = power def attack(self): print(self.name, "이(가) 공격을 수행합니다. [공격력:", self.power, "]") class Monster(Unit): def __init__(self, name, power, type): self.name = name self.power = power self.type = type def show_info(self): print("몬스터 이름:", self.name, "/ 몬스터 종류:", self.type) monster = Monster("슬라임", 10, "초급") monster.show_info() monster.attack()
상속을 받은 자식 클래스가 부모 클래스와 동일한 메소드나 변수를 가진다면, 자식 클래스의 것을 우선적으로 처리한다는 특징이 있따.
 

2) 활용

클래스는 머신러닝 프로그램을 작성할 때 자주 사용된다.
  • 클래스 : 붕어빵 틀에 비유할 수 있다.
  • 인스턴스 : 붕어빵 틀에서 생성된 붕어빵에 비유할 수 있다.
간단히 사람(human)에 대한 정보를 담는 사람 클래스를 정의해 보자!
프로그램 내에서 두 명의 사람을 처리한다면?
  • 각 사람은 나이(age)가 다를 수 있다.
 
아래 코드를 확인하고, 클래스의 기본적인 사용 방법을 이해해보자. ^^
class Human: def __init__(self): self.age = 0 def old(self): self.age += 1 human1 = Human() # 사람1 인스턴스 생성 human2 = Human() # 사람2 인스턴스 생성 for i in range(10): # for문 돌 때마다 age 하나씩 업뎃 human1.old() # 10세 for i in range(20): human2.old() # 20세 # 각 사람 인스턴스의 나이 출력 print(human1.age) print(human2.age)
클래스(class)는 여러 정보를 하나의 객체에 담을 때 사용할 수 있다.
학생 관리 프로그램을 만들 때, 학생에 대한 정보는 다양하다.
  • ① 학번, ② 이름, ③ 나이, ④ 성별, ⑤ 학과
 
학생 인스턴스를 생성함과 동시에 정보를 초기화 할 수 있다.
  • 생성자 : 인스턴스가 생성될 때 자동으로 실행되는 __init()__메서드를 의미한다.
self는 인스턴스(instance) 자기 자신을 의미함.
해당 인스턴스가 가지는 값과 함수의 인자 값을 구분하여 이해해야 한다.
 
__init()__함수 내부를 고려해보자.
  • self.name : 현재 인스턴스의 name 변수
  • name : 함수의 파라미터로 넘어 온 name 변수
class Student: def __init__(self, id, name, 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() student1.add_age(30) # 나이 더하기 student1.show()
output)
notion image
  • self의 동작 방식에 대하여 바르게 이해할 필요가 있다. 우리는 아래와 같이 클래스의 메서드를 호출한다.
  • 클래스의 메서드 호출
student1.add_age(5)
  • 이때 student1 → self에 대응되고, 값 5 → offset에 대응된다.
  • 클래스 메서드 구현
def add_age(self, offset): self.age += offset
 
 
  • 각 인스턴스의 인스턴스 변수는 서로 다르다.
  • 특정한 클래스(class)의 모든 인스턴스끼리 공유되는 정보가 필요하다면?
    • 클래스 변수 : 해당 클래스에서 전체적으로 공유되는 변수
      • Client의 클래스 변수는 Client클래스의 네임스페이스에 존재한다.
    • 인스턴스 변수 : 구체적인 하나의 인스턴스에서 사용되는 변수
      • client1의 인스턴스 변수는 client1 인스턴스의 네임스페이스에 존재한다.
# 전체 공유되는 변수와 하나의 인스턴스에서 사용되는 변수 차이 확인하기 !! 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)
notion image
 
  • 특정한 기준에 따라서 다수의 인스턴스를 정렬하고 싶을 때가 있다.
    • 예를 들어 포인트 값이 큰 순서대로 정렬하려면 어떻게 하면 될까?
    • 간단히 다음과 같이 key 속성의 값의 값으로 익명 함수를 넣을 수 있다.
      • 이후 뒤집기(reverse)를 수행하면, point에 대하여 내림차순 정렬이 완료된다.
key = lambda x: x.point
 
  • 또한 It 함수는 A가 B보다 작다는 의미를 정의할 때 사용한다. (less than)
    • It 함수를이용하여 정렬 기능을 구현할 수 있으며, 예시는 다음과 같다.
    • 이후에 단순히 리스트에 대하여 sort() 함수를 적용하면, 정렬이 완료된다.
    • def __lt__(self, other): return self.point < other.point
      class Cilent: 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()
      notion image
 
  • 클래스의 상속(inheritance)은 체계적인 프로그램 개발을 위해 필요하다.
  • 예를 들어 학교 관리 프로그램에서는 선생님(teacher)과 학생(student)에 대한 정보가 모두 활용된다.
    • 이들은 공통적으로 이름(name), 나이(age) 등의 정보를 가지고 있다.
    • 또한, 인적사항 정보를 출력하는 메서드를 둘다 사용한다.
  • 상속을 사용하여, 공통적으로 사용되는 변수를 매번 선언하지 않는다.
class Human: def __init__(self, name, age): self.name = name self.age = age def show_human(self): print("===== 인적 사항 =====") print(f"이름: {self.name}") print(f"나이: {self.age}")
  • 교사 클래스가 사람 클래스에 대한 정보를 상속 받기 위해서는 상속을 진행해야 한다.
  • 기본적인 형식은 바로 다음과 같다.
class 자식 클래스 이름(부모 클래스 이름):
pass
  • super()는 부모 클래스의 속성 및 메서드를 가져와야 할 때 사용할 수 있다.
  • super.init() 메서드를 호출하며, 이것은 부모 클래스에서 정의되어 있던 생성자를 사용한다는 의미다.
class Teacher(Human): def __init__(self, name, age, teacher_id, subject, salary): super().__init__(name, age) #메서드를 호출 : 부모 클래스에서 정의되어 있던 생성자를 사용 self.teacher_id = teacher_id self.subject = subject self.salary = salary def show_teacher(self): print("===== 교직원 카드 =====") print(f"교직원 번호: {self.teacher_id}") print(f"담당 과목: {self.subject}") print(f"월급: {self.salary}") teacher = Teacher("김순자", 40, 1, "사회", 450) teacher.show_human() teacher.show_teacher()
notion image
class Student(Human): def __init__(self, name, age, student_id, grade, score): super().__init__(name, age) self.student_id = student_id self.grade = grade self.score = score 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()
notion image
  • 실제로 머신러닝 분야에서 TensorFlow와 PyTorch 프레임워크를 사용할 때는 다양한 클래스를 상속 받아 사용할 수 있다.
  • 따라서, 다양한 머신러닝 모델을 정의하고 학습을 진행하기 위해 클래스(class)에 대한 개념 숙지가 필수적이다.
  • 다양한 기능이 라이브러리 형태(클래스 형태)로 제공되기 때문에, 상속을 받아 사용하는 것이 일반적이다.
    • 일반적으로 기본 라이브러리의 코드(부모 클래스)를 직접적으로 수정하지 않는다.
    • 우리가 만들 머신러닝 프로그램에 맞게 적절히 상속 받아 사용한다.
    •