class Car :
def __init__(self,name,model,color):
self.name = name
self.model = model
self.color = color
def show(self):
print("Name : ",self.name)
print("Model : ",self.model)
print("Color : ",self.color)
car = Car("Toyota","Corolla","Black")
print(car.name)
car.show()
지금까지 우리는 인스턴스 객체에 대한 메서드를 구현해왔기 때문에 이를 인스턴스 메서드(instance methods)라고 불렀다.
인스턴스 메서드는 첫번째 매개변수로 self를 받는데 이것이 인스턴스 메서드의 특징이다.
self를 통해 인스턴스를 참조할 수 있다는 점을 기억하자.
물론 인스턴스 메서드를 성공적으로 사용하기 위해서는 먼저 인스턴스가 존재 해야할 것이다.
아래 사진과 같이 self는 다른 단어를 사용할 수 있지만, 코드의 일관성을 위해 self로 명명한다.
(사진내 init 블럭을 확인)
규칙에 따라 self는 문자 그대로 인스턴스의 참조를 의미한다.
객체 지향 접근 방식을 통해 두가지 유형의 방법을 사용할 수 있다.
- 클래스 메서드
- 정적 메서드
이러한 유형은 방법을 이해하고, 클래스를 사용하는 능력을 확장하는 것이지,
이를 사용하기 위해 반드시 클래스 인스턴스를 만들 필요가 없다.
클래스 메서드 (Class methods)
클래스 메서드는 클래스 변수처럼 인스턴스화된 클래스 객체가 아닌 클래스 자체에서 동작하는 메서드를 의미한다.
즉, 객체가 아닌 클래스에 바인딩된 메서드라고 할 수 있다.
유용하게 사용되는 사례는 다음과 같다.
- 생성된 인스턴스의 수나 마지막으로 생성된 객체에 부여된 일련변호에 대한 정보를 담고 있는 클래스 변수에 대한 액세스를 제어하거나 클래스 변수의 상태를 수정한다.
- 클래스 메서드가 대체 생성자에 의해 구현될 수 있도록, 대체 방식으로 클래스 인스턴스를 생성해야한다.
암묵적인 사용 약속은 다음과 같다.
- 클래스 메서드와 인스턴스 메서드를 구별하기 위해 @classmethod 데코레이터를 사용하여 표시한다.
- 클래스 메서드의 첫번째 매개변수는 cls 로 명명하여 클래스 속성을 참조하는데 사용한다.
self와 마찬가지로 cls는 다른 이름을 사용할 수 있으나 일관되게 사용하기 위해 이를 지켜준다.
class Car :
__counter = 0 #클래스 private 변수
def __init__(self,name):
Car.__counter +=1 #클래스 변수 접근
self.name = name
@classmethod
def get_counter(cls):
return 'cls.__counter :'+str(cls.__counter)
car1 = Car("Toyota")
print(Car.get_counter())
car2 = Car("Hyundai")
print(Car.get_counter())
해당 get_counter() 메서드는 클래스 메서드로, 적절히 데코레이터를 활용하여 Python 인터프리터에 전달하였다.
또 , cls 매개변수를 활용하여 Car 클래스에 적합한 클래스 변수에 접근한다.
물론 네임 맹글링을 이용하여 해당 변수에 접근할 수 있다.
2025.03.19 - [Developer/Python] - python : 변수
print(Car._Car__counter)
# 2
하지만 이렇게 할 경우 규칙에 어긋나고 코드 자체가 의미를 전달하는 효과가 떨어지게 된다.
예외적으로는 __init__()메서드인데, 정의상 인스턴스 메서드임으로 "cls"를 사용하는 것이 아닌 Car 접두사를 통해 클래스 변수를 참조한다. (Car.__counter)
클래스 추가 인자 처리하기
class Car :
def __init__(self,vin):
print("Car init..")
print("vin :", vin)
self.vin = vin
@classmethod
def including_brand(cls, vin, brand):
print("Car Classmethod..")
_car = cls(vin)
_car.brand = brand
return _car
car1 = Car("ABC")
print()
car2 = Car.including_brand("DEF","Hyundai")
including_brand는 클래스 메서드이며, 두개의 매개변수가 필요하다.
해당 클래스 메서드는 car 인스턴스를 추가작업하고 반환하고 있다.
클래스 메서드를 이용한 DEF는 기본 생성의 ABC와 다르게 brand가 추가작업 되었음을 알 수 있다.
정적 메서드 (Static methods)
정적 메서드는 코드를 실행하기 위해 객체(self)나 클래스(cls) 자체를 나타내는 매개변수를 필요하지 않다.
유용하게 사용하기 위한 사례는 다음과 같다.
- 클래스와 의미적으로 관련있으나, 코드를 실행하기 위해 해당 클래스의 객체가 필요하지 않은 유틸리티 메서드가 필요한 경우.
- 따라서 정적메서드는 객체나 클래스의 상태를 알 필요가 없다.
암묵적 약속은 다음과 같다.
- 정적 메서드를 다른 메서드들과 구분하기 위해 메서드 정의 앞에 @staticmethod 데코레이터를 정의한다.
- 정적 메서드는 객체나 클래스의 상태를 수정하는 메서드를 허용하지 않기 때문에, 수정할 수 없다. (cls나 self가 없어 참조 불가능)
class Car :
def __init__(self,vin):
print("Car init..")
print("vin :", vin)
self.vin = vin
@staticmethod
def validate(vin):
print("Car staticmethod..")
if len(vin) == 8:
return True
else:
return False
print(Car.validate("ABC"))
정적 메서드를 사용하는 예시
예를 들어 휴대폰 번호를 11자리를 꼭 써야한다라고 생각해보자.
그렇다면 이 11자리에 대한 validate를 활용할 수 있다.
class Phone:
def __init__(self,phone_number):
self.phone_number = phone_number
@staticmethod
def validate(phone_number):
return len(phone_number) == 11
numbers_list = ['01033334444','010222233','010111222','01055556666']
for number in numbers_list:
if Phone.validate(number):
print("validate TRUE :",number,",len :",len(number))
else:
print("validate FALSE :",number,",len :",len(number))
따로 validate하는 함수를 이용할 필요 없이, 관련있는 클래스 내부에 선언함으로써,
해당 내용을 유지보수하기 좋아진다는 장점이 있다.
정적 메서드와 클래스 메서드의 비교
비교 | 클래스 메서드 | 정적 메서드 |
첫번째 매개 변수 | 'cls' 필수 | 'cls' 필요하지 않음. |
접근성 | 클래스 상태나 메서드에 접근 가능 | 클래스 상태나 메서드에 접근 불가능 |
데코레이터 | @classmethod | @staticmethod |
사용처 | 객체 생성을 대체하는 방법 | 유틸리티 메서드에 불과함 |
'Developer > Python' 카테고리의 다른 글
[python] 캡슐화 (Encapsulation) (0) | 2025.06.23 |
---|---|
[python] 추상 클래스 (Abstract classes) (0) | 2025.06.21 |
[python] 데코레이터 (decorator) (1) | 2025.06.20 |
[python] 동적 함수 인수(*args, **kwargs) (0) | 2025.06.19 |
[python] 파이썬의 다형성(Polymorphism) (0) | 2025.06.19 |