SKN/01. python

04. 클래스와 상속

claovy☘️ 2025. 2. 24. 23:16

1.  클래스 개요

01. 클래스란

💡클래스는 객체 지향 프로그래밍을 지원하는 개념이다. 추상화된 데이터와 함수를 하나의 단위로 묶어 클래스를 만들 수 있고, 클래스를 사용해 인스턴스를 생성하여 객체 단위로 사용할 수 있다.

 

02. 클래스의 구성 요소

(1) 클래스 속성

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

 

(2) 메서드

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

 

(3) 생성자

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

class Person:    
    national = 'korea' # 클래스 속성
    language = 'korean'
    
    def __init__(self, name, age): # 생성자
        self.name = name # self는 메서드에 접근하기 위한 객체를 의미한다.
        self.age = age
    
    def greeting(self): # 메서드
        return '안녕하세요'
    
    def information(self):
        return "I'm from " + self.national + " and I use " + self.language + ". My name is " + self.name + ". I'm " + str(self.age)
    
    def favorite(self, color):
        return "I love " + color

 

03. 네임 스페이스와 스코프

  • 네임스페이스는 크게 다섯 가지로 나뉜다.
    • 1. 지역 네임스페이스 : 현재 함수나 메서드 내의 네임스페이스
    • 2. 인스턴스 네임스페이스 : 인스턴스 객체의 네임스페이스
    • 3. 클래스 네임스페이스 : 클래스 객체의 네임스페이스
    • 4. 전역 네임스페이스 : 모듈 내의 전역 네임스페이스
    • 5. 내장 네임스페이스 : 파이썬 내장 함수와 예외를 포함하는 네임스페이스
  • 네임스페이스 검색 순서는 가장 가까운 스코프 순서로 로컬>전역>빌트인 순이다.
# 전역 네임스페이스
variable = "global variable"
print('전역: ', variable)    # 전역:  global variable

def outer_function():
    # 외부 함수 네임스페이스
    variable = "outer variable"
    print('지역(외부 함수): ', variable)
    
    def inner_function():
        # 지역 네임스페이스
        variable = "inner variable"
        print('지역(내부 함수): ', variable)
    
    inner_function()

outer_function()    # 지역(외부 함수):  outer variable
                    # 지역(내부 함수):  inner variable

class TestClass:
    # 클래스 네임스페이스
    variable = "class variable"
    
    def __init__(self, value):
        self.variable = value  # 인스턴스 네임스페이스
    
    def class_function(self):
        variable = "local variable"
        print('클래스 지역: ', variable)

# 인스턴스 생성 및 메서드 호출
obj = TestClass("instance variable")
print('인스턴스: ', obj.variable)    # 인스턴스:  instance variable
obj.class_function()                # 클래스 지역:  local variable

 

04. global / nonlocal / private variable

  • global
    • 함수 내부에서 전역변수를 참조하거나 수정할 때 사용하여, 함수 내부에서 전역 변수에 접근할 수 있다
    • 설정 값을 전역적으로 유지하고 여러 함수에서 이 값을 변경하거나 참조할 때 유용하다
g_variable = "global variable"

def modify_global():
    global g_variable
    g_variable = "global modified in function"

print(g_variable)    # global variable
modify_global()
print(g_variable)    # global modified in function
  • nonlocal
    • 중첩 함수에서 바깥 함수의 변수를 참조하거나 수정할 때 사용하며, 중첩 함수에서 한 단계 바깥의 함수 변수에 접근할 수 있다.
    • 클로저나 함수형 프로그래밍 패턴에서 바깥 함수의 상태를 유지하고 수정하는 경우에 유용하다
def outer_function():
    variable = "outer variable"

    def inner_function():
        nonlocal variable
        variable = "outer modified in inner function"

    print(variable)
    inner_function()
    print(variable)

outer_function()    # outer variable
                    # outer modified in inner function
  • private variable
    • 객체 내부에서만 접근할 수 있는 private은 파이썬에 존재하지 않기 때문에 _을 통해 은닉 속성을 따로 설정할 수 있다.
class Character:
    def __init__(self, nickname, type):
        self.nickname = nickname      # Public attribute
        self.__type = type            # Private attribute

    def get_type(self):
        return self.__type

    def set_type(self, type):
        character_types = ['전사', '법사', '치유사']
        for given_type in character_types:
            if(type == given_type):
                self.__type = type
                return
        
        raise ValueError("잘못된 캐릭터 타입을 선택하였습니다.")

my_character = Character("산골짜기다람쥐", "전사")

print(my_character.nickname)    # 산골짜기다람쥐

# Private attribute에 직접 접근 시도 (실패)
try:
    print(my_character.__type)    # 'Character' object has no attribute '__type'
except AttributeError as e:
    print(e)

# Private attribute에 접근하는 public method 사용
print(my_character.get_type())    # 전사

# Public method를 통해 private attribute 수정
my_character.set_type("법사")
print(my_character.get_type())    # 법사

# 잘못된 값으로 수정 시도
try:
    my_character.set_type("흑마법사")    # 잘못된 캐릭터 타입을 선택하였습니다.
except ValueError as e:
    print(e)

2. 인스턴스

01. 인스턴스란

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

 

02. 인스턴스 속성

  • 인스턴스 변수는 인스턴스별 데이터를 위한 것이고, 클래스 변수는 클래스의 모든 인스턴스에서 공유되는 어트리뷰트와 메서드를 위해 사용한다.
  • 클래스 속성은 공유되는 속성으로 변경이 발생하면, 전체 객체에서 변될 수 있다
class Character:    
    skills = []
    
    def __init__(self, nickname, type):
        self.nickname = nickname
        self.type = type
        
    def add_skill(self, skill):
        self.skills.append(skill)
    
    def show_skill(self):
        return self.type + ' ' + self.nickname + '님의 보유 스킬 ' + str(self.skills)

my_character = Character('산골짜기다람쥐', '전사')
your_character = Character('흑염룡의고릴라', '법사')
my_character.add_skill('곤봉 휘두르기')
your_character.add_skill('마법진 그려서 날려버리기')

print(my_character.show_skill())    # 전사 산골짜기다람쥐님의 보유 스킬 ['곤봉 휘두르기', '마법진 그려서 날려버리기']
  • 따라서 객체마다 다른 데이터를 관리해야 하는 경우에는 인스턴스 속성으로 설정해야 한다.
class Character:        
    def __init__(self, nickname, type):
        self.nickname = nickname
        self.type = type
        self.skills = []
        
    def add_skill(self, skill):
        self.skills.append(skill)
    
    def show_skill(self):
        return self.type + ' ' + self.nickname + '님의 보유 스킬 ' + str(self.skills)

my_character = Character('산골짜기다람쥐', '전사')
your_character = Character('흑염룡의고릴라', '법사')
my_character.add_skill('곤봉 휘두르기')
your_character.add_skill('마법진 그려서 날려버리기')

print(my_character.show_skill())    # 전사 산골짜기다람쥐님의 보유 스킬 ['곤봉 휘두르기']
  • 인스턴스 속성과 클래스 속성으로 같은 이름을 사용하면, 인스턴스 속성을 우선한다
class Character:        
    nickname = '땅파먹는개미핥기'
    
    def __init__(self, nickname, type):
        self.nickname = nickname
        self.type = type

my_character = Character('산골짜기다람쥐', '전사')

print(my_character.nickname)    # 산골짜기다람쥐

3. 상속

01. 상속이란

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

 

02. 상속 기본문법

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

 

03. 상속의 특징

(1) 다중 상속 지원

  • 부모를 여러 개 가지는 다중 상속을 지원한다
  • 다중 상속 시 검색 순서는 왼-오
class Person:
    national = 'korea'
    
    def greeting(self):
        return 'Hello. This is Python'

class Learner:
    def greeting(self):
        return 'Hello. I am Learner'
    
    def learn(self):
        return 'I am learning Python'

class Student(Person, Learner):
    pass

student = Student()
print(student.greeting())    # Hello. This is Python
print(student.learn())       # I am learning Python

 

(2) 다른 모듈의 클래스 상속 가능

class DerivedClassName(module_name.BaseClassName):
    <statement-1>
    .
    .
    .
    <statement-N>

 

(3) 부모 클래스의 속성 오버라이딩 가능

class Person:
    national = 'korea'
    
    def greeting(self):
        return 'Hello. This is Python'

class Learner(Person):
    def __init__(self, subject):
        self.subject = subject
    
    def learn(self):
        return 'I am learning ' + self.subject

class Student(Learner):
    def __init__(self, name, subject):
        Learner.__init__(self, subject)
        self.name = name;
    
    def greeting(self):
        return 'Hello. My name is ' + self.name

student = Student('토끼', 'python')
print(student.greeting())    # Hello. My name is 토끼
print(student.learn())       # I am learning python

'SKN > 01. python' 카테고리의 다른 글

08. Streamlit  (0) 2025.02.24
05. 모듈&패키지  (0) 2025.02.24
03. 함수  (0) 2025.02.18
02. 제어문(조건문, 반복문)  (0) 2025.02.18
01. 변수와 자료형  (0) 2025.02.18