📌 이 포스팅에서는 Python의 instance method, class method, static method에 대해 알아보겠습니다.
🔥 instance method
🔥 class method
🔥 static method
✔️ 인스턴스 매서드는 특별한게 아닙니다. 지금까지 배워 온 클래스 내부에 일반적인 함수를 인스턴스 매서드라합니다. 인스턴스 매서드는 인스턴스를 통해 호출할 수 있습니다.
✔️ 인스턴스로 매서드 호출 방법 방법 : 🔍 [인스턴스명].[인스턴스메서드명]
class Student(): # Class 변수 tuition_per = 1.0 # 수업료 인상률 def __init__(self, id, first_name, last_name, email, grade, tuition, gpa): self._id = id self._first_name = first_name self._last_name = last_name self._email = email self._grade = grade self._tuition = tuition self._gpa = gpa # Instance Method def full_name(self): return '{},{}'.format(self._first_name, self._last_name) # Instance Method def detail_info(self): return 'Student Detail Info : {}, {}, {}, {}, {}, {}'.format(self._id, self.full_name(), self._email, self._grade, self._tuition, self._gpa) # Instance Method def get_fee(self): return 'Before Tuition -> ID : {}, fee : {}'.format(self._id, self._tuition) # Instance Method def get_fee_culc(self): return 'After Tuition -> ID : {}, fee : {}'.format(self._id, self._tuition * Student.tuition_per) # 내장 매서드(__str__) : 객체를 호출하면 __str__이 호출되어 반환 def __str__(self): return 'Student Info -> name : {}, grade : {}, email : {}'.format(self.full_name(), self._grade, self._email) # 인스턴스 생성 student1 = Student(1, 'Kim', 'Sarang', 'student1@gmail.com', '1', 400, 3.5) student2 = Student(2, 'Lee', 'Myungho', 'student2@gmail.com', '2', 500, 4.3) print(student1) # Student Info -> name : Kim,Sarang, grade : 1, email : student1@gmail.com # 👈 str 매서드 반환 print(student2) # Student Info -> name : Lee,Myungho, grade : 2, email : student2@gmail.com # 👈 str 매서드 반환 # 인스턴스 매서드 호출 : 전체 정보 print(student1.detail_info()) # Student Detail Info : 1, Kim,Sarang, student1@gmail.com, 1, 400, 3.5 print(student2.detail_info()) # Student Detail Info : 2, Lee,Myungho, student2@gmail.com, 2, 500, 4.3
✔️ 등록금을 확인하기 위해서는 인스턴스 매서드인 "get_fee" 매서드를 통해 등록금을 반환받을 수 있습니다.
# 인스턴스 매서드 호출 : 학비 정보(인상 전) print(student1.get_fee()) # Before Tuition -> ID : 1, fee : 400 print(student2.get_fee()) # Before Tuition -> ID : 2, fee : 500 print()
✔️ 등록금 상승률은 "tuition_per"라는 클래스 변수에 담겨 있습니다. 인상 후 등록금 정보를 알기 위해서는 get_fee_culc 매서드를 이용하면 됩니다.
✔️ 단, 현재는 인상률이 1.0이기 때문에 인상 후 등록금의 변화가 없습니다. 등록금을 인상시키기 원한다면 클래스 변수에 접근하여 값을 수정해주어야 합니다.
✔️ 클래스 변수인 "tuition_per"에 접근하여 값을 수정하고 "get_fee_culc" 매서드를 호출시키면 인상 후 등록금이 반환됩니다.
Student.tuition_per = 1.2 # 등록금 20% 인상 # 인스턴스 매서드 호출 : 학비 정보(인상 후) print(student1.get_fee_culc()) # After Tuition -> ID : 1, fee : 480.0 print(student2.get_fee_culc()) # After Tuition -> ID : 2, fee : 600.0
✔️ 클래스 변수에 직접 접근하면 데이터 무결성, 보안 등 취약점에 노출되기 때문에 권장되는 방법은 아닙니다.
✔️ 이럴 경우에 클래스 변수에 간접적으로 접근할 수 있도록 해주는 클래스 메서드를 사용할 수 있습니다.
✔️ 클래스 매서드를 이용하면, 클래스 변수에 간적적으로 접근할 수도 있고 클래스 매서드를 통해 객체를 생성할 수도 있습니다.
✔️ 클래스 매서드를 생성하려면, classmethod 데코레이션을 선언해야 합니다.
✔️ 클래스 매서드는 첫번째 인자로 cls를 받고, 이 cls는 class 자체를 가르킵니다. 이에 반에 인스턴스 매서드에서 사용했던 self는 생성된 인스턴스를 가르킵니다.
✔️ 클래스 매서드로 생성자 선언(__init__
)을 이용하여 객체를 생성할 수도 있습니다. 이 또한 첫번째 인자 cls이고, 이 cls 자체가 class를 의미하기 때문에 속성에 해당하는 값을 return해주기만 하면 객체를 만들어줍니다.
class Student(): # Class 변수 tuition_per = 1.0 # 수업료 인상률 def __init__(self, id, first_name, last_name, email, grade, tuition, gpa): # 코드 생략 def full_name(self): # 코드 생략 def detail_info(self): # 코드 생략 def get_fee(self): # 코드 생략 def get_fee_culc(self): return 'After Tuition -> ID : {}, fee : {}'.format(self._id, self._tuition * Student.tuition_per) # Class Method @classmethod # 👈 classmethod 데코레이션 def reaise_fee(cls, per): # 👈 cls를 첫번째 인자로 받습니다(cls == Student) if per < 1: print('Please Enter 1.0 or More') return cls.tuition_per = per # 👈 == Student.tuition_per print('Successed! tuition increased!') # Class Method @classmethod def student_const(cls, id, first_name, last_name, email, grade, tuition, gpa): return cls(id, first_name, last_name, email, grade, tuition*cls.tuition_per, gpa) ... ... # 인스턴스 생성 student1 = Student(1, 'Kim', 'Sarang', 'student1@gmail.com', '1', 400, 3.5) student2 = Student(2, 'Lee', 'Myungho', 'student2@gmail.com', '2', 500, 4.3) # 클래스 매서드 사용 : 클래스 메서드를 통해 클래스 변수를 간접 제어(50% 인상) Student.reaise_fee(1.5) # 👈 class 매서드를 실행시켜, 클래스 변수의 값을 간접 제어 print(student1.get_fee_culc()) # After Tuition -> ID : 1, fee : 600.0 print(student2.get_fee_culc()) # After Tuition -> ID : 2, fee : 750.0 # 클래스 매서드를 통해 객체 생성 student_3 = Student.student_const(3, 'Park', 'Minji', 'student3@gmail.com', '3', 550, 4.5) student_4 = Student.student_const(4, 'Cho', 'Sunghan', 'student4@gmail.com', '4', 600, 4.1) # 호출 print(student_3.detail_info()) # Student Detail Info : 3, Park,Minji, student3@gmail.com, 3, 550.0, 4.5 print(student_4.detail_info()) # Student Detail Info : 4, Cho,Sunghan, student4@gmail.com, 4, 600.0, 4.1 # 학생 변경된 학비 확인 print(student_3._tuition) # 825.0 print(student_4._tuition) # 900.0
✔️ 인스턴스를 가르키는 "self"나 클래스 자체를 가르키는 "cls"를 받지 않고 공통으로 사용할 수 있는 매서드가 필요할 때 스타틱 매서드를 사용합니다.
✔️ 이에 스타틱 매서드는 인스턴스로 호출할 수 있고, 클래스로도 호출 가능하기 때문에 유연하다는 장점을 갖고 있습니다.
class Student(): # Class 변수 tuition_per = 1.0 # 수업료 인상률 def __init__(self, id, first_name, last_name, email, grade, tuition, gpa): # 코드 생략 def full_name(self): # 코드 생략 def detail_info(self): # 코드 생략 def get_fee(self): # 코드 생략 def get_fee_culc(self): return 'After Tuition -> ID : {}, fee : {}'.format(self._id, self._tuition * Student.tuition_per) # Class Method @classmethod def student_const(cls, id, first_name, last_name, email, grade, tuition, gpa): return cls(id, first_name, last_name, email, grade, tuition*cls.tuition_per, gpa) # Static Method @staticmethod def is_scholarship_static(inst): if inst._gpa >= 4.3: return '{} is a scholarship recipient.'.format(inst._last_name) return 'Sorry, Not a cholarship recipient.' # 인스턴스 생성 student_1 = Student(1, 'Kim', 'Sarang', 'student1@gmail.com', '1', 400, 3.5) student_2 = Student(2, 'Lee', 'Myungho', 'student2@gmail.com', '2', 500, 4.3) # 클래스 매서드를 통해 인스턴스 생성 방법 student_3 = Student.student_const(3, 'Park', 'Minji', 'student3@gmail.com', '3', 550, 4.5) student_4 = Student.student_const(4, 'Cho', 'Sunghan', 'student4@gmail.com', '4', 600, 4.1) # 장학금 혜택 여부(스타틱 메소드 사용) # 클래스명으로 호출 print(Student.is_scholarship_static(student_1)) # Sorry, Not a cholarship recipient. print(Student.is_scholarship_static(student_2)) # Myungho is a scholarship recipient. print(Student.is_scholarship_static(student_3)) # Minji is a scholarship recipient. print(Student.is_scholarship_static(student_4)) # Sorry, Not a cholarship recipient. print() # 인스턴스명으로 호출 print(student_1.is_scholarship_static(student_1)) # Sorry, Not a cholarship recipient. print(student_2.is_scholarship_static(student_2)) # Myungho is a scholarship recipient. print(student_3.is_scholarship_static(student_3)) # Minji is a scholarship recipient. print(student_3.is_scholarship_static(student_3)) # Sorry, Not a cholarship recipient.
✔️ 학점이 4.3 이상인 경우 장학금 대상이라 할 때, class 밖에서 함수를 생성해 지급 가능 여부를 확인할 수 있습니다.
# 인스턴스 생성 student_1 = Student(1, 'Kim', 'Sarang', 'student1@gmail.com', '1', 400, 3.5) student_2 = Student(2, 'Lee', 'Myungho', 'student2@gmail.com', '2', 500, 4.3) # 클래스 매서드를 통해 인스턴스 생성 방법 student_3 = Student.student_const(3, 'Park', 'Minji', 'student3@gmail.com', '3', 550, 4.5) student_4 = Student.student_const(4, 'Cho', 'Sunghan', 'student4@gmail.com', '4', 600, 4.1) # 장학금 혜택 여부(스타틱 메소드 미사용) def is_scholarship(inst): if inst._gpa >= 4.3: return '{} is a scholarship recipient.'.format(inst._last_name) return 'Sorry, Not a cholarship recipient.' print(is_scholarship(student_1)) # Sorry, Not a cholarship recipient. print(is_scholarship(student_2)) # Myungho is a scholarship recipient. print(is_scholarship(student_3)) # Minji is a scholarship recipient. print(is_scholarship(student_4)) # Sorry, Not a cholarship recipient.
✔️ 다만, 이보다는 클래스의 기능과 유사한 관계와 밀접한 관계를 지닌다면 class안에 매서드로 만들어 사용하는 것이 보다 코드 관리의 유용합니다.
✔️ 이럴 경우, self, cls를 받지 않고 공통으로 누구나 호출할 수 있는 스타틱 매서드를 사용하는데, 스타틱 매서드는 staticmethod 데코레이션 선언하여 사용합니다.
✔️ 스타틱 매서드는 cls, self이 필요하지 않고, 필요한 값만 parameter로 전달하용 사용합니다.
@staticmethod def is_scholarship_static(inst): if inst._gpa >= 4.3: return '{} is a scholarship recipient.'.format(inst._last_name) return 'Sorry, Not a cholarship recipient.'