본문 바로가기
Python 기초

[Python/파이썬] OOP 2 클래스/인스턴스 변수-메서드(+static메서드)

by 파프리카_ 2021. 1. 27.
728x90
반응형

목차

  1. 인스턴스 & 클래스 변수
    1. 인스턴스변수
    2. 클래스 변수
    3. 인스턴스 vs 클래스 간의 namespace
  2. 메서드 종류
    1. 인스턴스 메서드
    2. 클래스 메서드
    3. static(정적) 메서드
  3. 정리

 


1. 인스턴스(Instance) & 클래스(class) 변수

인스턴스 변수 vs 클래스 변수

인스턴스 변수는 각 개별 인스턴스에서 사용하는 변수이고,

클래스 변수는 인스턴스로 찍어 가더라도 모든 인스턴스에서 공통적으로 사용하는 변수이다.

😫 무슨 말인지 모르겠다구용?

이 글을 끝까지 읽으신 후, 다시 올라와서 보시면 '후후 그렇지🤭' 하며 공감하실 거예요.

 

1-1. 인스턴스 변수

  • 인스턴스의 속성! (attribute)
  • 각 인스턴스들마다의 고유한 변수
  • 메서드 정의에서는 self.변수명으로 정의할 수 있다.
  • 인스턴스 생성 이후에느는 인스턴스명.변수명으로 접근 및 할당이 가능하다.

클래스 정의 및 생성자를 통한 인스턴스 변수 초기화

class Person:
    # 생성자로 인스턴스 변수 초기화(정의, 할당)
    # => __init__ 함수는 인스턴스 메서드 중 특별한 생성자입니다!(constructor)
    def __init__(self, name):
        self.name = name     # 인스턴스 변수 정의/할당
                             # self : 개별 인스턴스 자기 자신을 뜻하기 때문!

Pesron class의 인스턴스를 생성하여 각각의 name 변수를 출력해보자.

iu = Person('iu')
iu.name
'iu'

생성자에 첫번째 param값인 name'iu'를 할당해주어,

인스턴스명.변수명 즉, ui.name으로 접근할 수 있었다.

 

다른 값을 넣어도 동일하게 적용된다.

yewool = Person('sleep yewool')
yewool.name
'sleep yewool'

 

1-2. 클래스 변수

  • 클래스의 속성(attribute) 값이다.
  • 모든 인스턴스에서 공유된다
  • 클래스 선언 내부에서 정의한다.
  • 클래스.변수명으로 접근 및 할당 가능하다.

클래스 생성(정의) 및 클래스 변수를 지정해보자.

class Person:
    # 클래스 내에 변수를 지정 => 클래스 변수
    species = '사람'

클래스 변수를 반환해보자.

Person.species
'사람'

생성한 클래스를 이용해 인스턴스를 생성해보자.

iu = Person()

클래스 변수에 접근해보자

iu.species
'사람'

클래스 변수는 모든 인스턴스에서 공유하는 변수이기 때문에, 인스턴스에서도 접근 가능하다.
하지만 이 때는 iu라는 인스턴스 변수로써 species가 반환받아진 것이다.

🙄 why? 인스턴스.변수 방법으로 접근했기 때문에!

그래서 인스턴스 변수인 species를 인스턴스 변수로 접근하여 재할당할 경우에는

iu.species = '신'
iu.species    # 신

이렇게 인스턴스 내의 변수로서 재할당하여 사용할 수 있다.

하지만 클래스.변수로 접근한 클래스 변수는 변함이 없다.

Person.species
'사람'

 

1-3. 인스턴스 vs 클래스 간의 namespace

1-3-1. 이름공간 탐색 순서

  1. 클래스 정의 => 클래스의 이름 공간 (namespace)이 생성됨
  2. 인스턴스 생성 => 인스턴스 객체 생성 => 인스턴스 객체의 이름 공간(namespace) 생성됨

중요중요

class와 instance는 서로 다른 namespace를 가지고 있다!
서로 다른 공간에 저장된다!

  1. 인스턴스 변수(attribute)가 변경되면,
    변경된 데이터를 인스턴스 객체의 이름공간에 저장한다.

    => 즉, 인스턴스에서 특정한 변수(attribute)에 접근하게 되면,

    인스턴스 -> 클래스 순으로 탐색을 한다.

클래스 생성 및 인스턴스 메서드 및 변수 정의

class Room:

    # 인스턴스 메서드
    def __init__(self, furniture):
        # 인스턴스 변수
        self.furniture = furniture

    # 인스턴스 메서드
    def introduce(self):
        # 인스턴스 변수 활용
        print(f'제 방에는 {self.furniture}가 있습니다.')

room1 인스턴스를 만들어서 인스턴스 메서드를 사용해봅시다.

room1 = Room('bed')
room1.introduce()
제 방에는 bed가 있습니다.

인스턴스 변수는 생성된 인스턴스의 인스턴스 메서드 내에서 잘 활용이 된다.

 

만약, 인스턴스 변수가 아닌 클래스 변수로 furniture를 정의하면 어떻게 될까요?

class Room:

    # 클래스 변수 정의 -> 클래스 공간에 저장
    furniture = 'desk'

    # 인스턴스 메서드
    def introduce(self):
        # 인스턴스 변수 활용
        print(f'제 방에는 {self.furniture}가 있습니다.')

room2 인스턴스를 만들어서 인스턴스 메서드를 사용해봅시다.

room2 = Room() # __init__(생성자)가 없기 때문에, 인스턴스 생성 단계에서 argument를 넣어주지 않아도 됩니다 - 즉, 인스턴스 변수가 정의된 적이 없다.
room2.introduce()
제 방에는 desk가 있습니다.

room2 인스턴스에서 introduce(self) 메서드를 실행할 때는,

furniture라는 특정 attribute에 접근하고자 합니다.

하지만 생성자, 즉 instacne단계에서 정의해준 적이 없기 때문에, class 변수에서 정의된 값을 반환해옵니다.

 

✨ 다시 기억하기! ✨

특정 attribute 탐색 시, 인스턴스 공간 -> 클래스 공간 순으로 탐색을 한다.

📌 정리

  • 인스턴스 변수 : 인스턴스 메서드 내의 self 키워드를 통해 지정된 변수
    • 인스턴스.변수 형태로 접근할 수 있다.
  • 클래스 변수 : 클래스 바로 아래에 클래스 영역에 지정된 변수
    • 클래스.변수 형태로 접근할 수 있다.
  • 변수 탐색 순서는 인스턴수 변수 -> 클래스 변수 순이며,
    인스턴스 변수가 정의가 되지 않은 경우, 클래스 변수에서 탐색을 한다.

 


2. 메서드의 종류

2-1. 인스턴스 메서드 (instance method)

인스턴스 메서드는 인스턴스를 조작하기 위한 함수이다.

이를 조작하기 위해서는 함수로 값을 넘겨야한다!

파이썬은 자바와 달리 self키워드만 parameter에 기입해주면, 인스턴스에서 활용할 수 있도록 알아서 값을 넘겨준다.

class MyClass:

    # 인스턴스 메서드
    def instance_method(self):
        return self

2-2. 클래스 메서드 (class method)

  • 클래스가 사용할 메서드이다.

  • @classmethod 데코레이터를 사용하여, 클래스 메서드임을 명시해주고 정의해준다.

  • 인스턴스 없이 호출 가능!

  • 목적: 클래스 속성(변수)에 접근할 때 사용 - 클래스 전체에서 공유하는 변수

  • 호출 시, 첫번째 인자로 클래스 cls가 전달된다.

class MyClass:
    class_variable = 10

    # 클래스 메서드
    @classmethod
    def get_class(cls, arg1, ...):
        return cls.class_variable
# 인스턴스 생성
mc = MyClass()

# 클래스 메서드를 통해 클래스 변수 접근 가능!
# => 자동으로 첫 번째 인자로 클래스(MyClass가 들어간다.)
print(mc.get_class()) # 10

 

🙋‍♀️🙋‍♀️🙋‍♀️여기서 잠깐 !!!!!

혹시 당신, Java의 @annotation과 Python의 @decorator가 비슷하다고 생각하십니까?

네, 오산입니다 !!

그 둘은 많이 다릅니다.


파이썬의 데코레이터는 그 이름에서 알 수 있듯, 기본적으로는 본체를 꾸며주는 역할을 합니다. 데코레이터(@classmethod, @staticmethod)를 추가함으로서 @classmethod or @staticmethod에 뭔가가 더해지기는 했지만,
기본적으로 get_method(), 그리고 뒤에 나올 static_method()가 바뀌는 것은 아닙니다!

즉, 메서드 자체의 성질이 변하는 것은 아닙니다.

 

2-3. 스태틱 메서드 (static method)

  • 클래스가 사용할 메서드
  • @staticmethod 데코레이터를 사용하여 정의
  • 목적 : 클래스와 클래스 속성(변수)에 접근할 필요가 없을 때 사용한다.
    • 정적 메서드는 cls, self와 같이 묵시적인 첫번째 인자를 받지 않기 때문
  • 호출 시, 어떠한 인자도 전달되지 않음
class MyClass:

    # 스태틱 메서드
    @staticmethod
    def static_method(arg):
        return arg


# 아무런 일도 자동으로 일어나지 않는다.
MyClass.static_method(.., ..)

인스턴스는 스태틱 메서드에 접근 가능합니다.

# 인스턴스 생성
mc = MyClass()

# 인스턴스의 스태틱 메서드 접근
mc.static_method(1)   # 1
# => static method는 self나 cls로 인스턴스 혹은 클래스를 받지 않기 때문에,
#    메서드 호출 뒤 자동으로 넘겨받는 것은 없고,
#    static_method(1)과 같이 argument를 꼭 기입해줘야 동작을 하게됩니다!

 


3. 정리

  1. 인스턴스는 세 가지 메서드 모두에 접근할 수 있다.
    1. 인스턴스 메서드
    2. 클래스 메서드
    3. 스태틱 메서드
  2. 하지만, 인스턴스에서 클래스 메서드와 스태틱 메서드를 호출하는 것은 권장되지 않는다.
  3. 인스턴스가 할 행동은 모두 인스턴스 메서드로 한정지어 설계하자!
728x90
반응형