일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- bootcamp
- 리뷰
- 코딩테스트
- 꾸준히
- yolo
- 선형회귀
- 코드스테이츠
- python
- pandas
- Codestates
- 재미져
- 딥러닝
- 파이썬
- 주간보고
- 노마드코더
- 열심히
- JavaScript
- selenium
- leetcode
- 2021
- 자료구조
- 성실히
- MYSQL
- 기초통계
- 독서
- Ai
- SQL
- 빅데이터
- 부트캠프
- 매일매일
- Today
- Total
코딩일기
[PYTHON 3] 객체지향 프로그래밍 {Class method}(feat. Codestates _AI_BootCamp, 부트캠프) 본문
[PYTHON 3] 객체지향 프로그래밍 {Class method}(feat. Codestates _AI_BootCamp, 부트캠프)
daje 2021. 3. 13. 15:43
안녕하십니까 다제입니다.
오늘은 클래스 메소드를 언제, 어떻게, 왜 사용해야하는지에 대해서 집중적으로 다루어 보고자 합니다.
해당 내용에 대한 개념이 안잡혀 있으시면 실제 프로그래밍을 할때 많이 햇갈리실 수 있습니다.
개념은 쉬운데 코드로 마주쳤을 때 난감한 개념이니 같이 공부해볼까요?
우리는 앞서 User.count와 user1.count를 통해서 인스턴스가 클래스의 변수를 접근하는 방법에 대해서 살펴보았습니다.
그렇다면, 클래스 내부에서 특정 함수가 클래스의 변수를 사용하려고 한다면 어떻게 해야할까요?
number_of_users가 User class의 count 변수를 이용하려고 한다면 어떻게 해야할까요?
일단, 틀린 코드 -> 정답 코드 순으로 설명드리겠습니다.
<틀린 코드>
class User:
count = 0
def __init__(self, name, email, password):
self.name = name
self.email = email
self.password = password
User.count += 1
def __str__(self):
return f"{self.name}, {self.email}"
def greet(self):
print(f"{self.name}님, 안녕하세요")
def number_of_users(User):
print(f"{User.count}")
user1 = User("홍길동", "123@gmail.com", "123456")
user2 = User("심청이", "456@gmail.com", "123456")
User.number_of_users()
user1.number_of_users()
<정답 코드>
class User:
count = 0
def __init__(self, name, email, password):
self.name = name
self.email = email
self.password = password
User.count += 1
def __str__(self):
return f"{self.name}, {self.email}"
def greet(self):
print(f"{self.name}님, 안녕하세요")
@classmethod
def number_of_users(cls):
print(f"{cls.count}")
user1 = User("홍길동", "123@gmail.com", "123456")
user2 = User("심청이", "456@gmail.com", "123456")
User.number_of_users()
user1.number_of_users()
@classmethod, cls, user1.number_of_users()에 self를 넘겨주지 않는 점 등이 새롭게 보신 부분일텐데요
하나하나 설명 드리겠습니다.
1) @classmethod
number_of_users라는 함수가 count라는 변수를 사용하기 위해서는 class User에게 승인을 받아야합니다.
그 승인을 해주는 코드가 @classmethod입니다. 그리고 승인을 받았으니 number_of_users에게 승인 카드 같은게 발급되었겠지요? 바로 그게 self 대신에 사용하는 cls라고 생각하시면 됩니다.
2) cls
인스턴스 메소드는 첫번째 파라미터인 self로 인스턴스 자신이 자동으로 전달되는 규칙이 있습니다.
클래스 메소드에서는 첫번째 파라미터 class가 자동 전달되는 규칙이 있고 이는 cls로 기재합니다.
아래와 같이 cls를 qwe로 변경하여도 정상적으로 작동은 합니다.
@classmethod
def number_of_users(qwe):
print(f"{qwe.count}")
self와 마찬가지로 다른 변수명으로 기재해도 되지만,
클래스 메소드에서 첫번째 파라미터는 cls로 기재하기로 약속하였으니 약속을 지켜주세요
cls에 또 다른 예를 facebook parlai github에서 찾아보았습니다. 참고하시면 좋을듯 합니다.
class BackgroundWorkerDynamicBatchWorld(DynamicBatchWorld):
@classmethod
def launch_process(cls, index, opt, model_agent, process_queue):
import torch
torch.set_num_threads(1) # prevent threads from spawning in this worker
logging.info(f"Launching background on Index {index}")
opt = copy.deepcopy(opt)
opt['background_index'] = index
try:
world = cls(opt, model_agent=model_agent, process_queue=process_queue)
while True:
world.parley()
except Exception:
import traceback
여기서도 launch_process function이 BackgroundWorkerDynamicBatchWorld class의 변수를 사용하기 위해 @classmethod가 기재되어 있고, 받는 인자가 self 대신 cls가 기재되어 있는 것을 볼 수 있습니다. 또한, 변수를 사용할 때 cls() 이런 식으로도 사용할 수 있습니다.
3) 클래스 메소드를 사용하는 방법(user1.number_of_users())
클래스 메소드를 사용하는 방법은 위에서 언급드린 바와 같이 2가지가 있습니다.
[ 클래스 메소드 사용방법 ]
① User.number_of_users()
② user1.number_of_users()
먼가 이상하지 않나요?
인스턴스 메소드에서 인스턴스를 호출할 때는 클래스를 이용할 때는 user1를 넘겨주었는데
그런 먼가 부가적인게 있지 않을까? 하는 생각이 들지 않으시나요?
기억 안나시는 분들을 위해 greet함수로 예시를 보여드리겠습니다.
[ 인스턴스 메소드 사용방법 ]
① User.greet(user1)
② user1.greet()
아니면 user1만 기재해주었는데 어떻게 2가 출력이 되었는지 궁금하실거 같은데요
@classmethod가 user1를 User로 변환해주는 작업을 보이지 않게 하여 아무것도 적어주지 않아도 됩니다.
햇갈리는 개념에 대해서 3가지 질문을 드리도록 하겠습니다.
1. 그럼 언제 클래스 메소드를 사용해야 할까요?
클래스 변수를 사용하면 클래스 메소드를 사용할 때와 인스턴스 변수를 사용하면 인스턴스 메소드를 사용할 때 입니다.
인스턴스 변수와 인스턴스 메소드는 모두 클래스로부터 정보를 상속받을 수 있기 때문입니다.
2. 클래스변수와 인스턴스 변수를 둘 다 쓸때는 어떤 변수를 사용해야할까요?
정답은 인스턴스 변수를 사용해야합니다.
클래스 메소드는 인스턴스 변수를 가져올 수 있는 방법이 아에 없습니다.
인스턴스 메소드는 상속을 받아서 클래스 변수를 가져올 수 있으나, 클래스 변수를 그럴 수 없기 때문입니다.
3. 만약 유저가 생성되어 있지 않은 상태에도 유저가 0명이라고 명시해야 할 때는 어떤 변수를 사용해야할까요?
클래스 매소드를 사용해야합니다. 인스턴스가 없는 경우는 인스턴스 변수를 사용할 수 없기 때문이죠!
위와 같이 클래스 메소드에 대해서 학습해 보았습니다.
코드 작성 시, 매우 햇갈리는 개념이이니 꼭 이해가 안되시면 댓글 부탁드립니다.
공감도 부탁드려요~ 감사합니다.