WeniVooks

검색

견고한 파이썬

클래스 심화

1. 클래스 메서드와 정적(static) 메서드

Python의 클래스에는 일반적인 인스턴스 메서드 외에도 클래스 메서드와 정적(static) 메서드라는 두 가지 특별한 유형의 메서드가 있습니다. 이들 메서드는 @classmethod@staticmethod 데코레이터를 사용하여 정의됩니다.

1.1 클래스 메서드 (@classmethod)

클래스 메서드는 클래스에 작용하는 메서드입니다. 클래스 메서드는 첫 번째 인자로 클래스 자체를 받습니다. 일반적으로 이 인자를 cls로 명명합니다. 클래스 메서드는 클래스 상태를 변경하는 데 사용될 수 있습니다.

class MyClass: count = 0 @classmethod def increment(cls): cls.count += 1 MyClass.increment() print(MyClass.count) # 출력: 1
1.2 정적(static) 메서드 (@staticmethod)

정적(static) 메서드는 클래스나 인스턴스와는 독립적으로 작동하는 메서드입니다. 정적 메서드는 selfcls 같은 특별한 첫 번째 인자를 받지 않습니다. 정적 메서드는 주로 클래스와 연관은 있지만 인스턴스나 클래스 상태에는 접근하지 않는 메서드에 사용됩니다.

class MyClass: @staticmethod def my_method(x, y): return x + y print(MyClass.my_method(5, 3)) # 출력: 8

아래와 같이 과목에 관련된 클래스를 만들었다고 했을 때 academic_warning에서는 self를 이용한 접근이 되지 않습니다.

class CompletionList: def __init__(self): self.subject_list = [] def show(self): print(self.subject_list) def append(self, subject): self.subject_list.append(subject) @staticmethod def academic_warning(subject): ''' 내부에서 클래스 변수, 인스턴스 변수 수정하는 것이 가능하지 않습니다. ''' if abs(1.5 - subject['grades']) >= 0: return True return False c = CompletionList() subject1 = {'name': 'Python', 'grades': 2.5} subject2 = {'name': 'HTML/CSS', 'grades': 3.5} c.append(subject1) c.append(subject2) c.show() print(c.academic_warning(subject1))

2. 속성 접근자와 덕 타이핑

2.1 속성 접근자 (Property)

Python에서는 @property 데코레이터를 사용하여 클래스의 메서드를 속성처럼 접근할 수 있게 만들 수 있습니다. 이를 통해 객체의 내부 상태를 보호하고, 특정 속성에 대한 접근을 제어할 수 있습니다.

class Person: def __init__(self, first_name, last_name): self._first_name = first_name self._last_name = last_name @property def full_name(self): return f'{self._first_name}{self._last_name}' licat = Person('li', 'cat') print(licat._first_name) print(licat._last_name) print(licat.full_name) # print(licat.full_name())

이 클래스의 인스턴스에서 full_name 속성에 접근하면, _first_name_last_name을 합친 문자열을 반환합니다. @property 데코레이터가 없다면, full_name() 메서드를 직접 호출해야 합니다.

2.2 속성 접근자의 값 설정

@property 데코레이터를 사용하면, 속성에 값을 할당할 때 setter 메서드를 사용할 수 있습니다. setter 메서드는 @property 데코레이터와 동일한 이름을 사용하며, @property 데코레이터의 이름 뒤에 .setter를 붙여 정의합니다. 이를 통해 속성에 대한 값을 설정할 때 추가적인 검증을 수행할 수 있습니다.

class Person: def __init__(self, name): self.name = name self._age = 0 @property def age(self): return self._age @age.setter def age(self, value): if value < 0: raise ValueError("나이는 음수일 수 없습니다.") self._age = value # 사용 예제 person = Person("홍길동") # age 속성 설정 person.age = 25 print(f"{person.name}의 나이는 {person.age}세입니다.")
2.3 덕 타이핑 (Duck typing)

"오리처럼 걷고, 오리처럼 꽥꽥대면 그것은 오리다."는 덕 타이핑의 원리를 잘 나타내는 문장입니다.

Duck Typing - 'If it walks like a duck and it quacks like a duck, then it must be a duck’

Duck typing

덕 타이핑은 실제 타입은 상관치 않고 구현된 메서드로 확인하는 방법입니다. 좀 더 어려운 말로 객체의 변수 및 메서드의 집합이 객체의 타입을 결정하는 개념을 의미합니다. 이를 통해 유연한 인터페이스를 구현할 수 있습니다.

class Duck: def quack(self): print('꽥꽥!') class Person: def quack(self): print("안녕하세요!") def quack(obj): obj.quack() duck = Duck() person = Person() quack(duck) # 출력: 꽥꽥! quack(person) # 출력: 안녕하세요!

위 코드에서 quack(obj) 함수는 obj가 실제로 Duck 타입이든 아니든 상관하지 않고, quack 메서드를 호출합니다. 이러한 접근법은 런타임에 메서드나 속성의 존재를 확인하기 때문에 코드가 더욱 유연해집니다.

{"packages":["numpy","pandas","matplotlib","lxml"]}
10.6 다중 상속10.8 메서드 오버라이딩