함수에 대한 기능의 확장을 위해 파이썬에서는 데코레이터를 사용한다.
최종수정일 : 2023.09.12
코드
class MyClass: myVal = 0 @staticmethod def change_val(val): MyClass.myVal = val class MyChildClass(MyClass): pass
실행결과
parent = MyClass() child = MyChildClass() parent.change_val(10) child.change_val(20) print(parent.myVal) #20 print(child.myVal) #20
함수를 해당 클래스의 네임스페이스에 집어넣었을 뿐, 전역 함수와 같은 양식으로 동작하기 때문에, 첫 번째 인자(argument)로 아무것도 넘기지 않는다.
따라서 해당 메서드로 클래스 변수를 변경하면 클래스 변수가 변경되며, 자식 객체에서도 똑같은 형식으로 작동한다.
코드
class MyClass: myVal = 0 @classmethod def change_val(cls, val): cls.myVal = val class MyChildClass(MyClass): pass
실행결과
parent = MyClass() child = MyChildClass() parent.change_val(10) child.change_val(20) print(parent.myVal) #10 print(child.myVal) #20
classmethod decorator을 적용한 경우, 해당 메서드는 호출하는 클래스에 대해 동적으로 작용한다. 따라서 위의 예에서는 호출하는 자식클래스에 대해 클래스 변수를 동적으로 생성하여 값을 대입하므로, 부모클래스의 동일이름의 클래스 변수는 그대로 유지된다.
코드
from abc import abstractmethod, ABCMeta class MyClass(metaclass = ABCMeta): @abstractmethod def child_method_unimplemented(): pass class MyChildClass(MyClass): pass
실행결과
child = MyChildClass() #TypeError: Can't instantiate abstract class MyChildClass with abstract method child_method_unimplemented
abstractmethod는 자식 클래스에서 구현해야만 할 메서드를 정의한다.
코드
from functools import singledispatch @singledispatch def my_generic_function(var): print("VAR") @my_generic_function.register(int) def _(var): print("INT") @my_generic_function.register(str) def _(var): print("STR")
결과
my_generic_function(1.0) #"VAR" my_generic_function(2) #"INT" my_generic_function("string") #"STR"
파이썬에서는 singledispatch를 지원하며, multiple dispatch는 과거 외부 라이브러리의 형태로 제공했다고 하나 현재에는 single dispatch를 사용한다. 싱글 디스패치를 통해 제네릭 함수를 구현할 수 있다.