Python

클래스(2)

haventmetyou 2023. 10. 18. 16:03
클래스와 인스턴스 속성 알아보기

클래스 속성 사용하기

class Person:
    bag = []    # 객체 관계없이 공통 사용

    def put_bag(self, stuff):
        self.bag.append(stuff)

james =  Person()    # james 객체 생성
james.put_bag('책')

maria = Person()     # maria 객체 생성
maria.put_bag('열쇠')

print(james.bag)
print(maria.bag)

# 실행 결과
['책', '열쇠']
['책', '열쇠']

클래스 속성은 클래스에 속해 있으며, 모든 인스턴스에서 공유

put_bag 메서드에서 클래스 속성 bag에 접근할 때 self를 사용했고, self는 현재 인스턴스를 뜻하므로 클래스 속성을 지칭하기에 모호함

class Person:
    bag = []    # 객체 관계없이 공통 사용

    def put_bag(self, stuff):
        Person.bag.append(stuff)    # 클래스 이름으로 클래스 속성에 접근

속성, 메서드 이름을 찾는 순서

인스턴스.__dict__

클래스.__dict__

print(james.__dict__)
print(Person.__dict__)

# 실행 결과
{}
{'__module__': '__main__', 'bag': ['책', '열쇠'],
'put_bag': <function Person.put_bag at 0x000001D6108ACC20>,
'__dict__': <attribute '__dict__' of 'Person' objects>,
'__weakref__': <attribute '__weakref__' of 'Person' objects>,
'__doc__': None}

인스턴스 속성 사용

class Person:
    def __init__(self):
        self.bag = []

    def put_bag(self, stuff):
        self.bag.append(stuff)

james =  Person()    # james 객체 생성
james.put_bag('책')

maria = Person()     # maria 객체 생성
maria.put_bag('열쇠')

print(james.bag)
print(maria.bag)

# 실행 결과
['책']
['열쇠']

클래스 속성: 모든 인스턴스가 공유, 인스턴스 전체가 사용해야 하는 값을 저장할 때 사용

인스턴스 속성: 인스턴스별로 독립되어 있음, 각 인스턴스가 값을 따로 저장해야 할 때 사용

 

비공개 클래스 속성 사용

# class 클래스이름:
#     __속성 = 값

class Knight:
    __item_limit = 10                 # private 클래스 속성

    def print_item_limit(self):
        print(Knight.__item_limit)    # 클래스 안에서만 접근 가능

x = Knight()
x.print_item_limit()          # 10 출력

print(Knight.__item_limit)    # 클래스 바깥에서는 접근할 수 없음, Error

# 실행 결과
    print(Knight.__item_limit)
          ^^^^^^^^^^^^^^^^^^^
AttributeError: type object 'Knight' has no attribute '__item_limit'.
Did you mean: 'print_item_limit'?

클래스와 메서드의 독스트링 사용

class Person:
    '''사람 클래스입니다'''
    
    def greeting(self):
        '''인사 메서드입니다'''
        print('hello')

print(Person.__doc__)             # 사람 클래스입니다
print(Person.greeting.__doc__)    # 인사 메서드입니다

maria = Person()
print(maria.greeting.__doc__)     # 인사 메서드입니다

# 실행 결과
사람 클래스입니다
인사 메서드입니다
인사 메서드입니다

 

정적 메서드 사용

인스턴스를 통하지 않고 클래스에서 바로 호출할 수 있는 정적 메서드, 클래스 메서드

# class 클래스이름:
#     @staticmethod
#     def 메서드(매개변수1, 매개변수2):
#         코드

class Clac:
    @staticmethod    # 정적 메서드
    def add(a, b):
        print(a + b)

    @staticmethod
    def mul(a, b):
        print(a * b)

Clac.add(10, 20)    # 클래스에서 바로 메서드 호출
Clac.mul(10, 20)

# 실행 결과
30
200

@staticmethod처럼 앞에 @이 붙은 것을 데코레이터라고 하고, 메서드(함수)에 추가 기능을 구현할 때 사용

정적 메서드는 self를 받지 않으므로 인스턴스 속성 접근 불가능

인스턴스 속성, 인스턴스 메서드가 필요 없을 때 사용

메서드의 실행이 외부 상태에 영향을 끼치지 않는 순수 함수(pure function)를 만들 때 사용

순수 함수: 부수 효과(side effect)가 없고, 입력 값이 같으면 언제나 같은 출력 값을 반환

인스턴스의 상태를 변화시키지 않는 메서드를 만들 때 사용

 

클래스 메서드 사용
# class 클래스이름:
#     @classmethod
#     def 메서드(cls, 매개변수1, 매개변수2):
#         코드

class Person:
    count = 0    # 클래스 속성

    def __init__(self):
        Person.count += 1    # 인스턴스가 만들어질 때
                             # 클래스 속성 count에 1을 더함

    @classmethod
    def print_count(cls):
        print('{}명 생성'.format(cls.count))    # cls로 클래스 속성에 접근

james = Person()
maria = Person()

Person.print_count()

# 실행 결과
2명 생성

첫 번째 매개변수 cls 지정(cls > class에서 따옴)

정적 메서드처럼 인스턴스 없이 호출

클래스 메서드는 메서드 안에서 클래스 속성, 클래스 메서드에 접근해야 할 때 사용

특히 cls를 사용하면 메서드 안에서 현재 클래스의 인스턴스를 만들 수도 있음

즉, cls는 클래스이므로 cls()는 Person()과 같다

> 현재 단계에서 중요한 건 아님... 나중에 필요할 때 다시 볼 것