staticmethod와 classmethod의 차이점


질문

 

@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를 사용하면 객체 인스턴스의 클래스가 암시 적으로 자체 대신 첫 번째 인수로 전달됩니다.

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

클래스를 사용하여 class_foo를 호출 할 수도 있습니다.사실, 당신이 무엇인가를 정의하면 ClassMethod는 클래스 인스턴스가 아닌 클래스에서 호출하려는 의도가 있기 때문일 수 있습니다.a.foo (1)은 TypeError를 제기했지만 a.class_foo (1)은 잘 작동합니다.

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

하나의 사용은 클래스 방법에 대해 발견 된 사람이 상속 가능한 대체 생성자를 만드는 것입니다.


staticMethods를 사용하면 자체 (오브젝트 인스턴스) 또는 CLS (클래스)는 암시 적으로 첫 번째 인수로 전달되지 않습니다.인스턴스 또는 클래스에서 호출 할 수있는 경우를 제외하고는 일반 함수처럼 작동합니다.

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

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

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


Foo는 단지 기능 일뿐 만 아니라 A.FOO를 호출 할 때 기능을 얻지 못합니다. 객체 인스턴스가 함수의 첫 번째 인수로 바인딩 된 함수의 "부분적으로 적용"버전을 얻습니다.Foo는 2 개의 인수를 기대하고 a.foo는 1 개의 논쟁만을 기대합니다.

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_foo는 1 개의 논쟁을 기대합니다 A.Static_Foo는 1 개의 논증도 기대합니다.

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

물론 Class A와 함께 static_foo를 호출하면 동일한 일이 발생합니다.

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


답변

staticMethod는 클래스 또는 인스턴스에 대해 아무 것도 알지 못하는 메소드입니다.전달 된 인수가 있고 암시 적 첫 번째 인수가 없습니다.기본적으로 Python에서 쓸모 없게됩니다 - STATICMETHOD 대신 모듈 기능을 사용할 수 있습니다.

반면에 클래스 메스 닷 (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에는 암시 적 인수가 없습니다.



답변

공식 파이썬 문서 :

@classmethod.

클래스 메소드는 클래스를 수신합니다 암시 적 첫 번째 주장, 인스턴스 메소드는 인스턴스를 수신합니다. 클래스 메소드를 선언하려면이를 사용하십시오 관용구: 클래스 C : @classmethod. DEF F (CLS, ARG1, ARG2, ...) : ... @ClassMethod 양식은 함수입니다 Decorator - 설명을 참조하십시오 기능의 기능 정의 자세한 내용은 정의. 그것은 클래스에서 호출 될 수 있습니다 (예 : C.F ()) 또는 인스턴스에서 (예 : c (). f ()).인스턴스가 있습니다 수업을 제외하고는 무시했습니다.만약 클래스 메소드가 파생 된 경우 호출됩니다 클래스, 파생 클래스 객체는입니다 묵시적 첫 번째 논쟁으로 전달됩니다. 클래스 메소드는 C ++와 다릅니다 또는 Java 정적 메소드.네가 원한다면 그것들은 이것에있는 staticmethod ()를 참조하십시오 부분.

@staticmethod.

정적 방법은 AN을받지 못합니다 암시 적 첫 번째 논쟁.A.를 선언하는 것은 정적 메소드,이 관용구를 사용하십시오 : 클래스 C : @staticmethod. DEF F (ARG1, ARG2, ...) : ... @StaticMethod 양식은 함수입니다 Decorator - 설명을 참조하십시오 기능의 기능 정의 자세한 내용은 정의. 그것은 클래스에서 호출 될 수 있습니다 (예 : C.F ()) 또는 인스턴스에서 (예 : c (). f ()).인스턴스가 있습니다 수업을 제외하고는 무시했습니다. 파이썬의 정적 메소드는 유사합니다 Java 또는 C ++에서 발견 된 것들.A. 고급 개념, 참조 이 섹션의 classmethod ().



답변

@StaticMethod 또는 @ClassMethod를 사용할지 여부를 결정하려면 메서드를 찾아야합니다.메서드가 클래스의 다른 변수 / 메소드에 액세스하는 경우 @classmethod를 사용하십시오.반면에 메서드가 클래스의 다른 부분에 닿지 않으면 @staticmethod를 사용하십시오.

class Apple:

    _counter = 0

    @staticmethod
    def about_apple():
        print('Apple is good for you.')

        # note you can still access other member of the class
        # but you have to use the class instance 
        # which is not very nice, because you have repeat yourself
        # 
        # For example:
        # @staticmethod
        #    print('Number of apples have been juiced: %s' % Apple._counter)
        #
        # @classmethod
        #    print('Number of apples have been juiced: %s' % cls._counter)
        #
        #    @classmethod is especially useful when you move your function to another class,
        #       you don't have to rename the referenced class 

    @classmethod
    def make_apple_juice(cls, number_of_apples):
        print('Making juice:')
        for i in range(number_of_apples):
            cls._juice_this(i)

    @classmethod
    def _juice_this(cls, apple):
        print('Juicing apple %d...' % apple)
        cls._counter += 1


답변

이 질문에 대한 짧은 기사가 있습니다

@StaticMethod 함수는 클래스 안에 정의 된 함수 이상입니다.클래스를 먼저 인스턴스화하지 않고도 호출 할 수 있습니다.상속을 통해 정의가 불가능합니다. @ClassMethod 기능은 클래스를 인스턴스화하지 않고도 호출 할 수 있지만 해당 정의는 상속을 통해 상위 클래스가 아닌 하위 클래스를 따릅니다.이는 @ClassMethod 함수의 첫 번째 인수가 항상 CLS (클래스)가되어야하기 때문입니다.

출처:https://stackoverflow.com/questions/136097/difference-between-staticmethod-and-classmethod