안녕하세요, 이전에 인스턴스 변수의 값을 읽거나 설정하는 인스턴스 메소드에 대해 정리하였었는데요, 오늘은 클래스 변수의 값을 읽거나 설정하는 메소드인 클래스 메소드에 대해 정리해보겠습니다.
먼저 아래 코드를 보며 설명드리겠습니다. User 클래스를 정의하고 user인스턴스를 만들 때마다 1씩 증가하는 클래스 변수 count를 정의해 주었습니다. 그 후 User인스턴스를 3개 만들고 count를 출력해보겠습니다.
class User:
count = 0
def __init__(self, name, email, password):
self.name = name
self.email = email
self.password = password
User.count += 1
def say_hello(self):
print("안녕하세요! 저는 {}입니다".format(self.name))
def __str__(self):
return "사용자: {}, 이메일: {}, 비밀번호: *****".format(self.name, self.email)
@classmethod
def number_of_users(cls):
print("총 유저 수는: {}입니다.".format(cls.count))
user1 = User("강호동","hodong@naver.com","12345")
user2 = User("유재석","seok@naver.com","12345")
user3 = User("하하","haha@naver.com","12345")
User.number_of_users() // 총 유저 수는: 3입니다. 출력된다
user1.number_of_users() // 총 유저 수는: 3입니다. 출력된다
우서 위의 코드를 보시면 클래스 메소드인 number_of_users 정의 위에 @classmethod가 보이시나요? 이렇게 @로 시작하는것을 데코레이터라고 하는데요, 클래스 메소드위에는 데코레이터가 있어야 합니다!
또한 클래스 메소드를 만들 때 규칙이 있는데요 바로 첫 번째 파라미터의 이름은 꼭! cls로 쓰기입니다. (인스턴스 메소드에서는 첫 번째 파라미터로 self를 사용하였습니다!) 이렇게 하면 클래스가 첫 번째 파라미터로 자동으로 전달됩니다.
클래스 메소드를 호출하는 것을 클래스 이름.클래스 메소드()로 호출하는 방법과 인스턴스 이름.클래스 메소드()를 사용하는 방법이 있습니다. 여기서 인스턴스 메소드와 클래스 메소드의 차이를 살펴보고 가겠습니다.
위의 코드에서 인스턴스 메소드(say_hello함수) 사용하는 방법으로는 아래 두 가지가 있습니다.
User.say_hello(user1) ← 파라미터로 인스턴스를 넣어줍니다!
user1.say_hello() ← 인스턴스(user1) 자신이 첫 번째 파라미터로 자동 전달됩니다!
그럼 클래스 메소드를 사용하는 방법을 살펴보겠습니다.
User.number_of_users()
user1.number_of_users()
차이가 보이시나요? 클래스(User)에서 함수를 부르던 인스턴스(user1)에서 함수를 부르던 둘 다 첫 번째 파라미터로 클래스가 자동 전달됩니다! 자동 전달되는 이유는 @classmethod(클래스 메소드 데코레이터)로 number_of_users함수를 클래스 메소드로 만들어 주었기 때문입니다!
클래스 메소드를 인스턴스 메소드로 바꿔도 사용이 가능합니다. 아래 코드에서 클래스 메소드 데코레이터를 삭제하고 cls대신 self를 넣어서 함수를 정의해보겠습니다. 여기서 실행시에 주의할 점은 기존에 User.number_of_users()는 클래스 메소드이기 때문에 파라미터가 자동 전달되었는데요, 인스턴스 메소드로 바꿨기 때문에 self를 꼭 파라미터로 넣어줘야 합니다!
class User:
count = 0
def __init__(self, name, email, password):
self.name = name
self.email = email
self.password = password
User.count += 1
def say_hello(self):
print("안녕하세요! 저는 {}입니다".format(self.name))
def __str__(self):
return "사용자: {}, 이메일: {}, 비밀번호: *****".format(self.name, self.email)
# @classmethod
# def number_of_users(cls):
# print("총 유저 수는: {}입니다.".format(cls.count))
def number_of_users(self):
print("총 유저 수는: {}입니다".format(User.count))
user1 = User("강호동","hodong@naver.com","12345")
user2 = User("유재석","seok@naver.com","12345")
user3 = User("하하","haha@naver.com","12345")
User.number_of_users() // 총 유저 수는: 3입니다. 출력된다
user1.number_of_users() // 총 유저 수는: 3입니다. 출력된다
여기서 클래스 메소드를 인스턴스 메소드로 바꿀 수 있었던 이유는 인스턴스 변수를 사용하고 있지 않았기 때문입니다! number_of_users함수 내용을 보시면 self가 하나도 사용되지 않았습니다. 클래스 메소드와 인스턴스 메소드 사용에 대해 정리를 해보겠습니다.
인스턴스 변수를 사용할 시에는 인스턴스 메소드를 사용하고, 클래스 변수를 사용할 시에는 클래스 메소드를 사용해줘야 합니다. 인스턴스 메소드는 인스턴스 변수와 클래스 변수 모두 사용이 가능하므로 만약 클래스 변수와 인스턴스 변수를 모두 사용한다면 인스턴스 메소드를 사용해주면 됩니다! 인스턴스 변수는 self를 이용해 사용하고 클래스 변수는 위의 예제와 같이 클래스 이름에 .을 붙여 사용합니다. 여기서 클래스 메소드는 인스턴스 변수를 사용할 수 없습니다ㅠㅠ
그럼 클래스 메소드는 언제 사용하여야 할까요? 바로 인스턴스가 없지만 클래스 변수를 사용할 때 사용해주면 됩니다! 위의 예제에서 보자면 user1/2/3을 생성하지 않고 count를 출력하고자 할 때는 클래스 함수로만 호출이 가능합니다!
마치며...
이렇게 인스턴스 메소드와 클래스 메소드에 대해 알아보았는데요, 솔직히 아직까지는 클래스 변수니 인스턴스 변수니 왜 사용하여야 할지 잘 정리가 안되지만 계속 공부하다 보면 알 수 있을 것 같은 느낌이 듭니다! 이후에는 실제로 객체를 만들어보는 연습을 해보겠습니다! 읽어 주셔서 감사합니다.
'Python > 객체지향 및 자료구조' 카테고리의 다른 글
객체 생성 연습 (0) | 2021.07.08 |
---|---|
가변 타입 / 불변 타입 (0) | 2021.07.04 |
__str__ 메소드 (0) | 2021.05.10 |
__init__ 메소드 (0) | 2021.05.08 |
인스턴스 메소드 / 변수 (0) | 2021.05.07 |
댓글