파이썬

[Python] @staticmethod와 @classmethod의 차이점

zooheon 2022. 7. 31. 14:01
반응형

@staticmethod로 장식된 기능 과 로 장식된 기능의 차이점은 무엇 @classmethod인가요?

 

약간의 예제 코드가 도움이 될 수 있습니다. foo, class_foo및 의 호출 서명의 차이점을 확인하십시오 static_foo.

class A(object):
    def foo(self, x):
        print(f"executing foo({self}, {x})")

    @classmethod
    def class_foo(cls, x):
        print(f"executing class_foo({cls}, {x})")

    @staticmethod
    def static_foo(x):
        print(f"executing static_foo({x})")

a = A()

다음은 개체 인스턴스가 메서드를 호출하는 일반적인 방법입니다. 개체 인스턴스 a는 암시적으로 첫 번째 인수로 전달됩니다.

a.foo(1)
# executing foo(<__main__.A object at 0xb7dbef0c>, 1)

classmethods 를 사용하면 개체 인스턴스의 클래스가 암시적으로 대신 첫 번째 인수로 전달됩니다 self.

a.class_foo(1)
# executing class_foo(<class '__main__.A'>, 1)

class_foo클래스를 사용하여 호출할 수도 있습니다 . 사실, 클래스 메서드로 무언가를 정의한다면 아마도 클래스 인스턴스가 아닌 클래스에서 호출하려고 하기 때문일 것입니다. A.foo(1)TypeError가 발생했지만 A.class_foo(1)잘 작동합니다.

A.class_foo(1)
# executing class_foo(<class '__main__.A'>, 1)

사람들이 클래스 메서드에 대해 찾은 한 가지 용도는 상속 가능한 대체 생성자 를 만드는 것 입니다.


staticmethods 를 사용하면 self(객체 인스턴스)도 cls(클래스)도 암시적으로 첫 번째 인수로 전달되지 않습니다. 인스턴스나 클래스에서 호출할 수 있다는 점을 제외하고는 일반 함수처럼 작동합니다.

a.static_foo(1)
# executing static_foo(1)

A.static_foo('hi')
# executing static_foo(hi)

Staticmethods는 클래스에 대한 클래스와 일부 논리적 연결이 있는 함수를 그룹화하는 데 사용됩니다.


foo는 단지 함수이지만 호출할 때 함수를 가져오는 것이 아니라 함수 에 대한 첫 번째 인수로 바인딩된 a.foo개체 인스턴스가 있는 함수의 "부분적으로 적용된" 버전을 얻습니다 . 2개의 인수를 예상하지만 1개의 인수만 예상합니다.afooa.foo

a에 바인딩됩니다 foo. 이것이 아래의 "묶인"이라는 용어의 의미입니다.

print(a.foo)
# <bound method A.foo of <__main__.A object at 0xb7d52f0c>>

a.class_foo사용하면 에 a바인딩되지 class_foo않고 클래스 A가 에 바인딩됩니다 class_foo.

print(a.class_foo)
# <bound method type.class_foo of <class '__main__.A'>>

여기에서 정적 메서드를 사용하면 메서드이지만 a.static_foo바인딩된 인수가 없는 좋은 ole 함수를 반환합니다. static_foo1개의 인수를 a.static_foo예상하고 1개의 인수도 예상합니다.

print(a.static_foo)
# <function static_foo at 0xb7d479cc>

static_foo물론 대신 클래스 를 호출할 때도 같은 일이 발생 A합니다.

print(A.static_foo)
# <function static_foo at 0xb7d479cc>

 

정적 메서드는 호출 된 클래스나 인스턴스에 대해 아무것도 모르는 메서드입니다. 암시적인 첫 번째 인수가 아닌 전달된 인수만 가져옵니다. Python에서는 기본적으로 쓸모가 없습니다. 정적 메서드 대신 모듈 함수를 사용할 수 있습니다.

반면 에 classmethod 는 호출된 클래스 또는 호출된 인스턴스의 클래스를 첫 번째 인수로 전달하는 메서드입니다. 이것은 메서드가 클래스의 팩토리가 되기를 원할 때 유용합니다. 첫 번째 인수로 호출된 실제 클래스를 가져오기 때문에 하위 클래스가 포함된 경우에도 항상 올바른 클래스를 인스턴스화할 수 있습니다. dict.fromkeys()예를 들어 , classmethod가 하위 클래스에서 호출될 때 하위 클래스의 인스턴스를 반환하는 방법을 관찰하십시오 .

>>> class DictSubclass(dict):
...     def __repr__(self):
...         return "DictSubclass"
... 
>>> dict.fromkeys("abc")
{'a': None, 'c': None, 'b': None}
>>> DictSubclass.fromkeys("abc")
DictSubclass
>>> 

 

기본적으로 @classmethod첫 번째 인수가 클래스 인스턴스가 아닌 호출된 클래스인 메서드에 @staticmethod암시적 인수가 없도록 만듭니다.

 

반응형