본문 바로가기

python & django & scipy

[python] self와 cls의 차이 / instance method, static method, class method의 차이

class MyClass:
	
    # instance method
    def instance_method(self, a):
    	print (a)
    
    # class method
    @classmethod
    def class_method(cls, a):
    	print (a)
    
    # static method
    @staticmethod
    def static_method(a):
    	print (a)

python class의 3가지 method를 위처럼 작성했다. 

 

 

1. instance  method

instance method는 첫번째 인자에 인스턴스가 들어가야한다.

instacne method는 자기자신을 인자로 받기 때문에 인스턴스의 속성에 접근하거나, 다른 instance method를 호출하거나 클래스 속성이나 class method에 접근할 수 있다. 

 

실행 예시)

>>>> myInstance = MyClass()
>>>> MyClass.instance_method(myInstace, 8)
8

>>>> myInstance.instance_method(8)
8

>>>> MyClass.instance_method(8)
Traceback (most recent call last):
  File "/Users/dare/Desktop/bunkerkids_proj/spark_django/venv/lib/python3.9/site-packages/IPython/core/interactiveshell.py", line 3251, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-6-4861bfa92e9d>", line 1, in <module>
    MyClass.instance_method(8)
TypeError: instance_method() missing 1 required positional argument: 'a'

 

2. class method, static method

class method와 static method는 인자에 인스턴스나 클래스가 들어갈 필요없이 바로 실행시킬 수 있다.

각각 @classmethod, @staticmethod 데코레이터로 선언한다. 

class method는 첫번째 인자로 cls를 받는데 이는 인스턴스가 아니라 클래스를 받는 것이다. 따라서 클래스 메소드나 클래스 속성에 접근할 수 있다. 

또한 class method와 static method는 다른 언어의 정적 메소드와 다르게 인스턴스를 사용해서 호출할 수도 있다. 

 

실행 예시)

>>>> MyClass.class_method(8)
8

>>>> MyClass.static_method(8)
8

>>>> myInstance.class_method(8)
8

>>>> myInstance.static_method(8)
8

 

잘못된 예시)

>>>> MyClass.class_method(MyClass, 8)
Traceback (most recent call last):
  File "/Users/dare/Desktop/bunkerkids_proj/spark_django/venv/lib/python3.9/site-packages/IPython/core/interactiveshell.py", line 3251, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-7-a820f2e61f5f>", line 1, in <module>
    MyClass.class_method(MyClass, 8)
TypeError: class_method() takes 2 positional arguments but 3 were given


>>>> MyClass.static_method(myInstance, 8)
Traceback (most recent call last):
  File "/Users/dare/Desktop/bunkerkids_proj/spark_django/venv/lib/python3.9/site-packages/IPython/core/interactiveshell.py", line 3251, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-9-0d92a44d2701>", line 1, in <module>
    MyClass.static_method(MyClass, 8)
TypeError: static_method() takes 1 positional argument but 2 were given


>>>> MyClass.static_method(MyClass, 8)
Traceback (most recent call last):
  File "/Users/dare/Desktop/bunkerkids_proj/spark_django/venv/lib/python3.9/site-packages/IPython/core/interactiveshell.py", line 3251, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-10-cafe3efab634>", line 1, in <module>
    MyClass.static_method(myInstance, 8)
TypeError: static_method() takes 1 positional argument but 2 were given

 

3. static method와 class method의 차이

위에서도 말했듯이 class method는 cls를 받아 클래스 메소드나, 클래스 속성에 접근할 수 있지만

static method는 인스턴스는 물론이며 클래스의 메소드, 속성에 접근할 수 없다. 클래스 바깥의 메소드와 동일하게 작동하지만 보통 클래스와 연관이 있다는 의미를 표현하기 위해 클래스 내부에 선언한다. 

따라서 보통 static method는 utility method를 작성할 때 사용하고, class method는 factory method로써 사용한다. 

자바에서는 두 method를 한 번에 묶어 static method라고 하고 method에 static을 붙여 선언해 사용한다

 

4. 결론

self vs cls

self는 instance, cls는 class

 

instance vs class vs static method

  instance  method class method static method
instance attribute 접근 o x x
class attribute 접근 o o x