Menu
Coddy logo textTech

정적 메서드와 클래스 메서드

Coddy Python 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 64개 중 39번째.

일반적인 인스턴스 메서드 외에도, 클래스는 서로 다른 용도로 사용되는 정적 메서드(static methods)와 클래스 메서드(class methods)를 가질 수 있습니다.

다음은 정적 메서드의 예시입니다:

class MathHelper:
    @staticmethod
    def add(a, b):
        return a + b
    
    @staticmethod
    def is_even(number):
        return number % 2 == 0

정적 메서드는 self가 필요하지 않으며 일반 함수처럼 작동합니다. 클래스에서 직접 호출하세요:

result = MathHelper.add(5, 3)
print(result)

check = MathHelper.is_even(10)
print(check)

다음은 클래스 메서드의 예입니다:

class Person:
    count = 0  # 클래스 변수
    
    def __init__(self, name):
        self.name = name
        Person.count += 1
    
    @classmethod
    def get_count(cls):
        return cls.count
    
    @classmethod
    def create_anonymous(cls):
        return cls("Anonymous")

클래스 메서드는 클래스 자체(cls)를 첫 번째 매개변수로 받습니다:

person1 = Person("Alice")
person2 = Person("Bob")
print(Person.get_count())  # 2

클래스 메서드를 대체 생성자로 사용하세요:

anonymous = Person.create_anonymous()
print(anonymous.name)      # Anonymous
print(Person.get_count())  # 3

한 클래스 내에서 세 가지 메서드 유형을 모두 비교해 보세요:

class Calculator:
    brand = "Python Calc"
    
    def __init__(self, owner):
        self.owner = owner
    
    # 인스턴스 메서드 - self가 필요하며, 인스턴스 데이터에 접근합니다
    def show_owner(self):
        return f"Owned by {self.owner}"
    
    # 클래스 메서드 - cls가 필요하며, 클래스 데이터에 접근합니다
    @classmethod
    def get_brand(cls):
        return cls.brand
    
    # 정적 메서드 - 둘 다 필요하지 않으며, 단순한 유틸리티 함수입니다
    @staticmethod
    def multiply(x, y):
        return x * y
calc = Calculator("Alice")
print(calc.show_owner())        # Alice 소유
print(Calculator.get_brand())   # Python 계산기
print(Calculator.multiply(4, 5)) # 20

출력:

8
True
2
Anonymous
3
Owned by Alice
Python Calc
20

인스턴스에서도 클래스 메서드와 정적 메서드를 호출할 수 있습니다:

calc = Calculator("Bob")
print(calc.get_brand())      # Python Calc
print(calc.multiply(2, 3))   # 6

주요 차이점:

  • 인스턴스 메서드: self가 필요하며, 인스턴스 데이터에 접근합니다
  • 클래스 메서드: cls가 필요하며, 클래스 데이터에 접근하고, 대체 생성자를 만드는 데 유용합니다
  • 정적 메서드: 둘 다 필요하지 않으며, 클래스와 관련된 단순 유틸리티 함수입니다

핵심 포인트: 클래스에 논리적으로 속하지만 클래스나 인스턴스 데이터가 필요하지 않은 유틸리티 함수에는 @staticmethod를 사용하세요. 대체 생성자나 클래스 변수 접근과 같이 클래스 자체에 접근해야 할 때는 @classmethod를 사용하세요.

challenge icon

챌린지

쉬움

이 챌린지에서는 포괄적인 테스트 프레임워크를 활용하면서 특정 기능을 가진 Temperature 클래스를 구현하게 됩니다.

구현을 안내하는 TODO 주석에 따라 temperature.py 파일 수정하면 됩니다. 클래스에는 다음이 포함되어야 합니다:

  • 온도 기록을 추적하기 위한 클래스 변수
  • 온도 변환을 위한 정적 메서드(static method)
  • 기록을 추가하고 평균을 계산하기 위한 클래스 메서드(class method)

치트 시트

클래스는 인스턴스 메서드, 정적 메서드(static methods), 클래스 메서드(class methods)의 세 가지 유형의 메서드를 가질 수 있습니다.

정적 메서드@staticmethod 데코레이터를 사용하며, self가 필요하지 않고 일반 함수처럼 작동합니다:

class MathHelper:
    @staticmethod
    def add(a, b):
        return a + b

# Call directly from class
result = MathHelper.add(5, 3)

클래스 메서드@classmethod 데코레이터를 사용하며 클래스(cls)를 첫 번째 매개변수로 받습니다:

class Person:
    count = 0
    
    def __init__(self, name):
        self.name = name
        Person.count += 1
    
    @classmethod
    def get_count(cls):
        return cls.count
    
    @classmethod
    def create_anonymous(cls):
        return cls("Anonymous")

# Usage
print(Person.get_count())
anonymous = Person.create_anonymous()

주요 차이점:

  • 인스턴스 메서드: self가 필요하며, 인스턴스 데이터에 접근합니다.
  • 클래스 메서드: cls가 필요하며, 클래스 데이터에 접근하고 대체 생성자를 만드는 데 유용합니다.
  • 정적 메서드: 둘 다 필요하지 않으며, 클래스와 관련된 단순한 유틸리티 함수입니다.

클래스 메서드와 정적 메서드 모두 클래스 또는 인스턴스에서 호출할 수 있습니다:

Calculator.multiply(4, 5)  # From class
calc.multiply(4, 5)        # From instance

직접 해보기

from temperature import Temperature

# 포괄적인 테스트를 위한 테스트 케이스 핸들러
test_case = input()

if test_case == "default_test":
    # 기본 기능 테스트
    Temperature.celsius_readings = []
    Temperature.add_reading(25)
    Temperature.add_reading(30)
    Temperature.add_reading(27)
    
    print(f"Average reading: {Temperature.average_reading()}")
    print(f"22°C is {Temperature.celsius_to_fahrenheit(22)}°F")

elif test_case == "empty_readings":
    # 측정값이 없을 때 average_reading 테스트
    Temperature.celsius_readings = []
    print(f"Average reading: {Temperature.average_reading()}")

elif test_case == "single_reading":
    # 단일 측정값으로 테스트
    Temperature.celsius_readings = []
    Temperature.add_reading(100)
    print(f"Average reading: {Temperature.average_reading()}")

elif test_case == "negative_values":
    # 음수 온도 값으로 테스트
    Temperature.celsius_readings = []
    Temperature.add_reading(-10)
    Temperature.add_reading(-20)
    Temperature.add_reading(-30)
    print(f"Average reading: {Temperature.average_reading()}")
    print(f"-15°C is {Temperature.celsius_to_fahrenheit(-15)}°F")

elif test_case == "zero_value":
    # 0°C 측정값으로 테스트
    print(f"0°C is {Temperature.celsius_to_fahrenheit(0)}°F")

elif test_case == "extreme_values":
    # 극한 온도 값으로 테스트
    absolute_zero = -273.15  # 섭씨 기준 절대 영도
    sun_surface = 5500  # 섭씨 기준 대략적인 태양 표면 온도
    
    print(f"{absolute_zero}°C is {Temperature.celsius_to_fahrenheit(absolute_zero)}°F")
    print(f"{sun_surface}°C is {Temperature.celsius_to_fahrenheit(sun_surface)}°F")

elif test_case == "reset_readings":
    # 측정값 초기화 테스트
    Temperature.celsius_readings = []
    Temperature.add_reading(10)
    Temperature.add_reading(20)
    Temperature.add_reading(30)
    print(f"Average reading before reset: {Temperature.average_reading()}")
    
    Temperature.celsius_readings = []
    print(f"Average reading after reset: {Temperature.average_reading()}")

elif test_case == "decimal_values":
    # 소수점 값으로 테스트
    Temperature.celsius_readings = []
    Temperature.add_reading(36.5)  # 정상 체온
    Temperature.add_reading(37.2)  # 미열
    Temperature.add_reading(36.9)  # 정상 범위 내 변화
    print(f"Average reading: {Temperature.average_reading()}")

elif test_case == "many_readings":
    # 많은 측정값으로 테스트
    Temperature.celsius_readings = []
    for i in range(1, 101):
        Temperature.add_reading(i)
    print(f"Average reading with 100 values: {Temperature.average_reading()}")
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

Object Oriented Programming의 모든 레슨