[참고] 저자 본인의 공부 및 참고용으로 쓰여진 글인점을 알려드립니다.
# 코딩도장의 내용입니다.
https://dojang.io/mod/page/view.php?id=2378
파이썬 코딩 도장: 35.1 클래스 속성과 인스턴스 속성 알아보기
Unit 35. 클래스 속성과 정적, 클래스 메서드 사용하기 지금까지 간단하게 클래스를 만들고 속성과 메서드를 사용해봤습니다. 이번에는 클래스에 속해 있는 클래스 속성에 대해 알아보겠습니다.
dojang.io
>>> james.__dict__
{}
>>> Person.__dict__
mappingproxy({'__module__': '__main__', 'bag': ['책', '열쇠'], 'put_bag': <function Person.put_bag at 0x028A32B8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None})
# 클래스 속성과 인스턴스 속성 알아보기
속성 : 클래스 속성 , 인스턴스 속성 이렇게 두 가지가 있다.
class attribute vs. instance attribute
__init__ 메서드에서 만들었던 속성은 인스턴스 속성 입니다.
* 속성(Attribute) : 클래스 내부에 포함돼 있는 메서드나 변수를 의미한다.
# 클래스 속성 사용하기
클래스 속성은 다음과 같이 클래스에 바로 속성(객체)을 만든다.
class 클래스이름 :
속성 = 값
class Person :
bag = []
def put_bag(self, stuff) :
self.bag.append(stuff) # instance attribute 을 사용
james = Person()
james.put_bag("책")
maria = Person()
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) # 클래스 이름으로 클래스 속성에 접근
Person.bag 이라고 하면 클래스 Person 에 속한 bag 속성이라는 것을 바로 알 수 있다. 마찬가지로 클래스 바깥에서도 다음과 같이 클래스 이름으로 클래스 속성에 접근하면 된다.
print(Person.bag)
참고 | 속성, 메서드 이름을 찾는 순서
파이썬에서는 속성, 메서드 이름을 찾을 때 인스턴스, 클래스 순으로 찾는다. 인스턴스 속성이 없으면 클래스 속성을 찾게 되므로 james.bag, maria.bag 도 문제 없이 동작한다. 겉보기에는 인스턴스 속성을 사용하는 것 같지만 실제로는 클래스 속성이다.
인스턴스와 클래스에서 __dict__ 속성을 출력해보면 현재 인스턴스와 클래스의 속성을 딕셔너리로 확인할 수 있다.
인스턴스.__dict__
클래스.__dict__
>>> james.__dict__
{}
>>> Person.__dict__
mappingproxy({'__module__': '__main__', 'bag': ['책', '열쇠'], 'put_bag': <function Person.put_bag at 0x028A32B8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None})
#인스턴스 속성 사용하기
그럼 가방(attribute) 를 여러 사람이 공유하지 않으려면 어떻게 해야 할까? 그냥 bag 을 인스턴스 속성으로 만들면 된다.
class Person :
def __init__(self) :
self.bag = []
def put_bag(self, stuff) :
self.bag.append(stuff)
james = Person()
james.put_bag('책')
maria = Person()
maria.put_bag('열쇠')
print(james.bag)
print(maria.bag)
james.bag과 maria.bag을 출력해보면 각자 넣은 물건만 출력됩니다. 즉, 인스턴스 속성은 인스턴스별로 독립되어 있으며 서로 영향을 주지 않습니다.
<<차이점 정리>>
클래스 속성 : 모든 인스턴스가 attribute 공유. 인스턴스 전체가 사용해야 하는 값을 저장할 때 사용
인스턴스 속성 : 인스턴스별로 독립되어 있음. 각 인스턴스가 값을 따로 저장해야 할 때 사용
# 비공개 클래스 속성 사용하기
클래스 속성도 비공개 속성을 만들 수 있다. 클래스 속성을 만들 때 __속성 과 같이 __(밑줄 두 개) 로 시작하면 비공개 속성이 된다. 따라서 클래스 안에서만 접근할 수 있고, 클래스 바깥에서는 접근할 수 없다.
class 클래스이름 :
__속성 = 값 # 비공개 클래스 속성
즉, 클래스에서 공개하고 싶지 않은 속성이 있다면 비공개 클래스 속성을 사용해야 한다. 예를 들어 기사 게임 캐릭터는 아이템을 최대 10개 까지 보유할 수 있다고 하자.
class Knight :
__item_limit = 10 # 비공개 클래스 속성
def print_item_limit(self) :
print(Knight.__item_limit) # 클래스 안에서만 접근할 수 있음
x = Knight()
x.print_item_limit() # 10
print(Knight.__item_limit) # 클래스 바깥에서는 접근할 수 없음.
실행을 해보면 클래스 Knight의 비공개 클래스 속성 __item_limit는 클래스 안의 print_item_limit 메서드에서만 접근할 수 있고, 클래스 바깥에서 접근하면 에러가 발생합니다. 아이템의 보유 제한이 10개인데, 이 클래스를 사용하는 사람이 마음대로 __item_limit = 1000으로 수정하면 곤란하겠죠?
이처럼 비공개 클래스 속성은 클래스 바깥으로 드러내고 싶지 않은 값에 사용합니다.
참고 | 클래스와 메서드의 독스트링 사용하기
함수와 마찬가지로 클래스와 메서드도 독스트링을 사용할 수 있습니다. 다음과 같이 클래스와 메서드를 만들 때 :(콜론) 바로 다음 줄에 """ """(큰따옴표 세 개) 또는 ''' '''(작은따옴표 세 개)로 문자열을 입력하면 됩니다. 그리고 클래스의 독스트링은 클래스.__doc__ 형식으로 사용하고, 메서드의 독스트링은 클래스.메서드.__doc__ 또는 인스턴스.메서드.__doc__ 형식으로 사용합니다
class Person:
'''사람 클래스입니다.'''
def greeting(self):
'''인사 메서드입니다.'''
print('Hello')
print(Person.__doc__) # 사람 클래스입니다.
print(Person.greeting.__doc__) # 인사 메서드입니다.
maria = Person()
print(maria.greeting.__doc__) # 인사 메서드입니다.
'Programming > Python' 카테고리의 다른 글
[클래스] 클래스 메서드 사용하기 (0) | 2023.03.13 |
---|---|
[클래스] 정적메서드 사용하기 (0) | 2023.03.13 |
[클래스] 비공개 속성 사용하기 (0) | 2023.03.12 |
[클래스] 속성 사용하기 (0) | 2023.03.12 |
[클래스] Class 사용하기 (0) | 2023.03.12 |