TIL09. Python : 매서드의 이해(instance, class, static)

ID짱재·2021년 9월 8일
0

Python

목록 보기
21/39
post-thumbnail

📌 이 포스팅에서는 Python의 instance method, class method, static method에 대해 알아보겠습니다.



🌈 매서드의 이해(instance, class, static)

🔥 instance method

🔥 class method

🔥 static method



1. instance 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

✔️ 클래스 변수에 직접 접근하면 데이터 무결성, 보안 등 취약점에 노출되기 때문에 권장되는 방법은 아닙니다.
✔️ 이럴 경우에 클래스 변수에 간접적으로 접근할 수 있도록 해주는 클래스 메서드를 사용할 수 있습니다.


2. class method

🤔 클래스 메서드 사용 방법

✔️ 클래스 매서드를 이용하면, 클래스 변수에 간적적으로 접근할 수도 있고 클래스 매서드를 통해 객체를 생성할 수도 있습니다.
✔️ 클래스 매서드를 생성하려면, 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

3. static method

🤔 스타틱 매서드는 왜 쓰나요?

✔️ 인스턴스를 가르키는 "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.'
profile
Keep Going, Keep Coding!

0개의 댓글