Python classmethod 개념 및 활용

python classmethod는 클래스 변수를 조작하는데 사용합니다. 클래스 변수는 무엇이고 classmethod는 무엇인지 정리하였습니다.

클래스 변수, 인스턴스 변수

간단히 말하면 클래스 변수는 클래스에서 생성된 모든 인스턴스에서 공유되는 변수 입니다. 반면 인스턴스 변수는 해당 인스턴스에서만 사용되는 변수 입니다.

1. 인스턴스 변수:

  • 인스턴스 변수는 클래스의 특정 인스턴스에 속하는 변수입니다.
  • 클래스의 각 인스턴스는 인스턴스 변수에 대해 서로 다른 값을 가질 수 있습니다.
  • 메소드 내에서, 일반적으로 self 키워드를 사용하여 __init__ 메소드 내에서 정의됩니다.
  • 아래 예에서 namer과 age는 인스턴스 변수이며 해당 값은 Person 인스턴스마다 다를 수 있습니다.
class Person:
    def __init__(self, name, age):
        self.name = name  # 인스턴스 변수
        self.age = age    # 인스턴스 변수

2. 클래스 변수:

  • 클래스 변수는 클래스의 모든 인스턴스에서 공유되는 변수입니다.
  • 메소드 외부, 클래스 본문 내에서 직접 정의됩니다.
  • 클래스 변수는 모든 인스턴스에서 공유되므로 self가 아닌 클래스 이름을 사용하여 액세스됩니다.
  • 이는 모든 인스턴스에 공통적인 속성이나 속성을 나타내는 경우가 많습니다.
  • 아래 예에서 ‘species’는 클래스 변수입니다. Dog 클래스의 모든 인스턴스는 동일한 species 값인 ‘Canine’을 공유합니다.
class Dog:
    species = 'Canine'  # 클래스 변수

    def __init__(self, name, age):
        self.name = name  # 인스턴스 변수
        self.age = age    # 인스턴스 변수

Python classmethod 사용법

인스턴스(‘self’)를 첫 번째 매개변수로 사용하는 일반 메소드와 달리 클래스 메소드는 클래스 자체를 전통적으로 'cls'라는 첫 번째 매개변수로 사용합니다.

클래스 메소드는 @classmethod 데코레이터를 사용하여 정의됩니다.

class MyClass:
    @classmethod
    def my_class_method(cls, arg1, arg2, ...):
        # 실행 코드 작성

클래스 메서드는 클래스 수준 속성이나 변수에 액세스하거나 수정하는데 사용합니다.

Python classmethod의 활용

저도 classmethod를 실제 프로젝트에 적용하여 사용한 적은 아직 없습니다…

그래도 하나의 예를 억지로? 만들어 보았습니다.

아래 코드는 대량의 데이터를 클래스의 인스턴스로 변환하여 조작하는 예입니다.

직원들의 이름, 나이, 연봉 데이터를 클래스 인스턴스로 만든 후, 1년이 지나면 모든 인스턴스에서 나이를 1 더하고 연봉 인상률을 변경하여 모든 인스턴스에 적용하는 코드 입니다.

import copy
import datetime

class Person:
    persons = []
    salary_increase = 1  # 연봉 인상률
    age_increase = 1

    def __init__(self, name, age, salary):
        self.name = name
        self.age = age
        self.salary = salary
        self.datetime = datetime.date.today()
        Person.persons.append(self)  # 인스턴스를 클래스 변수인 리스트에 저장

    def __repr__(self):
        return f"{self.datetime}: Person(name={self.name}, age={self.age}, salary={self.salary})"

    @classmethod
    def create_persons_from_data(cls, data_list):
        # Person 인스턴스를 딕셔너리 리스트로부터 생성한다
        for data in data_list:
            person = cls(data['name'], data['age'], data['salary'])
        return cls.persons
    
    @classmethod
    def set_salary(cls):
        origin_salary_increase = copy.deepcopy(cls.salary_increase)
        cls.salary_increase = 1.1
        print(f'연봉 인상폭이 {origin_salary_increase}에서 {cls.salary_increase}로 변경되었습니다.')
    
    def renew_age(self):
        origin_age = copy.deepcopy(self.age)
        self.age += Person.age_increase
        print(f'{self.name}의 나이가 {origin_age}에서 {self.age}로 변경되었습니다.')

    def renew_salary(self):
        origin_salary = copy.deepcopy(self.salary)
        self.salary = int(self.salary * Person.salary_increase)
        print(f'{self.name}의 연봉이 {origin_salary}에서 {self.salary}로 변경되었습니다.')



# ---코드 사용 예---:
data_list = [
    {'name': 'Alice', 'age': 25, 'salary':3000},
    {'name': 'Bob', 'age': 30, 'salary':4000},
    {'name': 'Charlie', 'age': 22, 'salary':5000}
]

# 인스턴스 생성
persons_li = Person.create_persons_from_data(data_list)
for person in persons_li:
    print(person)

# 모든 인스턴스의 연봉 인상률 변경
print()
Person.set_salary()
print()

# 나이와 연봉 변경
for person in persons_li:
    person.renew_age()
    person.renew_salary()
    print(person)

실행 결과는 아래와 같습니다.

2023-12-31: Person(name=Alice, age=25, salary=3000)
2023-12-31: Person(name=Bob, age=30, salary=4000)
2023-12-31: Person(name=Charlie, age=22, salary=5000)

연봉 인상폭이 1에서 1.1로 변경되었습니다.

Alice의 나이가 25에서 26로 변경되었습니다.
Alice의 연봉이 3000에서 3300로 변경되었습니다.
2023-12-31: Person(name=Alice, age=26, salary=3300)
Bob의 나이가 30에서 31로 변경되었습니다.
Bob의 연봉이 4000에서 4400로 변경되었습니다.
2023-12-31: Person(name=Bob, age=31, salary=4400)
Charlie의 나이가 22에서 23로 변경되었습니다.
Charlie의 연봉이 5000에서 5500로 변경되었습니다.
2023-12-31: Person(name=Charlie, age=23, salary=5500)

Leave a Comment

목차