Developer's Development

3.1.4 [Python] 클래스 본문

프로그래밍과 데이터 기초/PYTHON

3.1.4 [Python] 클래스

mylee 2025. 6. 30. 19:20
클래스

 

객체 지향 프로그래밍(OOP)을 지원하는 중요한 개념이다.

추상화된 데이터와 함수(메서드)를 하나의 단위로 묶어 클래스를 만들 수 있고, 클래스를 사용해 인스턴스를 생성하여 객체 단위로 사용할 수 있다.

 

  • 정의

class 키워드와 콜론을 이요해 클래스를 정의한다.

클래스 정의 시에도 클래스의 내용이 될 블록을 "반드시" 들여 쓰기 한다.

class 클래스명:
	<statement-1>
    .
    .
    .
	<statement-N>

 

  • 클래스 구성 요소

클래스 속성 : 클래스 자체에 속하는 변수로, 모든 인스턴스가 공유하는 속성이다.

인스턴스 속성 : 각 인스턴스마다 개별적으로 가지는 변수이며, 생성자에서 정의된다.

* 인스턴스 속성과 클래스 속성으로 같은 이름을 사용하면, 인스턴스 속성을 우선한다.

class Character:
    nickname = "맹구"  #클래스 속성

    def __init__(self, nickname):
        self.nickname = nickname  #인스턴스 속성
    
character = Character("짱구")
print(character.nickname)  #짱구

 

메서드(method) : 클래스 내부에 정의된 함수로, 인스턴스의 데이터를 조작하거나 동작을 정의한다.

self

메서드 내에서 쓰이는 self는 필드 및 메소드에 접근하기 위한 객체를 의미한다.

메소드 호출 시 객체의 주소값이 첫 번째 인자로 넘어오기 때문에, 객체를 통한 접근 시 호출되는 메서드의 첫 번째 인자는 항상 self여야 한다.

 

생성자 : __init__ 메서드는 객체가 생성될 때 자동으로 호출되는 메서드로, 생성자라고 부른다. 이 때 매개변수를 전달받아 인스턴스 속성을 초기화할 수 있다.

class Student:
    # 1. 클래스 속성
    dream = 'No.1 AI developer'

    # 2. 생성자 (-> 인스턴스 속성)
    def __init__(self, name, phone):
        self.name = name
        self.phone = phone
        # __init__() == 클래스명() 호출했을 때 호출되면서 인스턴스를 생성하는 메서드
        # 생성자 내부에 self.변수명 == 인스턴스 속성, 개별 인스턴스가 각각 다른 값 가짐
    
    # 3. 메서드
    def study(self):
        print(f'Hey {student.name}, study hard!')
        
student = Student('맹구', '없음')
print(student.name, student.phone)  #맹구 없음
student.study()  #Hey 맹구, study hard!

 

  • 심화

네임 스페이스는 크레 다섯 가지로 나누어 볼 수 있다.

  1. 지역(local) 네임스페이스 : 현재 함수나 메서드 내의 네임스페이스
  2. 인스턴스 네임스페이스 : 인스턴스 객체의 네임스페이스
  3. 클래스 네임스페이스 : 클래스 객체의 네임스페이스
  4. 전역(global) 네임스페이스 : 모듈 내의 전역 네임스페이스
  5. 내장(built-in) 네임스페이스 : 파이썬 내장 함수와 예외를 포함하는 네임스페이스
  • global

함수 내부에서 전역 변수를 참조하거나 수정할 때 사용하여, 함수 내부에서 전역 변수에 접근할 수 있다.

설정 값을 전역적으로 유지하고 여러 함수에서 이 값을 변경하거나 참조할 떄 유용하다.

  • nonlocal

중첩 함수에서 바깥 함수의 변수(로컬 변수를 포함)를 참조하거나 수정할 떄 사용하며, 중첩 함수에서 한 단계 바깥의 함수 변수에 접근할 수 있다.

클로저(closure)나 함수형 프로그래밍 패턴에서 바깥 함수의 상태를 유지하고 수정하는 경우에 유용하다.

  • Private Variable

객체 내부에서만 접근할 수 있는 private은 파이썬에 존재하지 않는다.

단, 대부분의 파이썬 코드에서 따르는 밑줄로 시작하는 네임스페이스를 가진 속성은 private 하게 취급된다는 규약을 통해 private 속성을 설정할 수 있다. (ex. __type)

 

 

인스턴스

 

클래스로 객체를 생성하면 메모리에 매번 서로 다른 주소를 가진 인스턴스가 할당된다. 인스턴스는 각각 독립적인 공간이 되며, 필드가 있을 경우 서로 다른 상태 값을 가진다.

  • 생성

클래스명 뒤에 소괄호(())를 붙여 객체를 생성한다.

클래스 내에 생성자(__init__ 메서드)가 정의되어 있는 경우, 생성자에서 사용하는 매개변수를 전달하면서 객체를 생성할 수 있다.

  • 인스턴스 속성

인스턴스 변수는 인스턴스별 데이터를 위한 것이고, 클래스 변수는 그 클래스의 모든 인스턴스에서 공유되는 어트리뷰트와 메서드를 위해 사용한다.

클래스 속성은 공유되는 속성으로 변경이 발생하면, 전체 객체에서 변경될 수 있다.

따라서 객체마다 다른 데이터를 관리해야 하는 경우에는 인스턴스 속성으로 설정해야 한다.

 

 

상속

 

부모 클래스를 상속 받는다는 것은 부모가 가지고 있는 속성이나 메서드를 자신의 것처럼 사용할 수 있다는 의미이다.

class 자식클래스명(부모클래스명):
	<statement-1>
    .
    .
    .
    <statement-N>
class Person:
    national = 'korea'
    
    def greeting(self):
        return 'Hello. This is Python'

class Student(Person):
    pass

student = Student()
print(student.greeting())    # Hello. This is Python
print(student.national)      # korea

 

👩‍👦 특징

  • 다중 상속 지원 (부모를 여러 개 가지는 다중 상속을 지원하며, 검색 순서는 왼쪽에서 오른쪽으로 탐색한다.)
  • 다른 모듈의 클래스 상속 가능
  • 부모 클래스의 속성 오버라이딩 가능 (ex. __init__)
class Person:
    def __init__(self, name, phone):
        self.name = name
        self.phone = phone

class Student(Person):
    def __init__(self, name, phone, hobby):
        # 방법 1. 직접 할당 (상속의 의미가 없음)
        # self.name = name
        # self.phone = phone

        # 방법 2. 부모클래스.__init__(self, ...)
        # Person.__init__(self, name, phone)

        # 방법 3(권장). super().__init__()
        super().__init__(name, phone)
        self.hobby = hobby
        
s1 = Student('맹구', '01011112222', '떡잎마을 지키기')
print(s1.name, s1.phone, s1.hobby)  #맹구 01011112222 떡잎마을 지키기

 

* 메서드 해결 순서(Method Resolution Order, MRO) 확인 속성 __mro__

: 파이썬에서 상속된 클래스 간의 메서드 호출 순서 규칙에 따른 MRO 리스트를 나타낸다.

Student.__mro__  #(__main__.Student, __main__.Person, object)

 

 

다형성
  • 같은 멤버 함수 호출에 대해 (상속 관계 내의) 다른 클래스의 인스턴스들이 각각 다르게 반응하도록 하는 기능이다.
  • 상속 관계가 없어도 적용 가능하다. → 자료형 선언이 없다는 점에서 파이썬에서는 다형성을 적용하기가 쉽다.
  • 실시간으로 객체의 타입이 결정되므로 단 하나의 메서드에 의해 처리될 수 있는 객체의 종류에 제한이 없다.
  • 연산자 중복 정의도 다형성을 지원하는 중요한 기술이다.
def plus_something(a, b):
    return a + b

print(plus_something(1, 2))  #3
print(plus_something("짱구", "맹구"))  #짱구맹구