programing

클래스 본문 내에서 클래스 스태틱 메서드를 호출하시겠습니까?

goodjava 2022. 11. 11. 23:34

클래스 본문 내에서 클래스 스태틱 메서드를 호출하시겠습니까?

클래스 본문 내에서 정적 메서드를 사용하고 빌트인을 사용하여 정적 메서드를 정의하려고 하면staticmethod이렇게 데코레이터로서 기능합니다.

class Klass(object):

    @staticmethod  # use as decorator
    def _stat_func():
        return 42

    _ANS = _stat_func()  # call the staticmethod

    def method(self):
        ret = Klass._stat_func() + Klass._ANS
        return ret

다음의 에러가 표시됩니다.

Traceback (most recent call last):
  File "call_staticmethod.py", line 1, in <module>
    class Klass(object): 
  File "call_staticmethod.py", line 7, in Klass
    _ANS = _stat_func() 
  TypeError: 'staticmethod' object is not callable

문제가 발생하는 이유(설명자 바인딩)이해하고 있으며 수동으로 변환하여 해결할 수 있습니다._stat_func()다음과 같이 마지막 사용 후 정적 방식으로 변환합니다.

class Klass(object):

    def _stat_func():
        return 42

    _ANS = _stat_func()  # use the non-staticmethod version

    _stat_func = staticmethod(_stat_func)  # convert function to a static method

    def method(self):
        ret = Klass._stat_func() + Klass._ANS
        return ret

제 질문은 다음과 같습니다.

    이를 달성하기 위한 더 깔끔한 방법이나 더 많은 "피토닉" 방법이 있습니까?

staticmethod물체에는 가 있는 것 같다__func__원래 원시 함수를 저장하는 속성(필요했던 의미)입니다.이 방법은 다음과 같습니다.

class Klass(object):

    @staticmethod  # use as decorator
    def stat_func():
        return 42

    _ANS = stat_func.__func__()  # call the staticmethod

    def method(self):
        ret = Klass.stat_func()
        return ret

덧붙여서 static method 객체에 원래 함수를 저장하는 속성이 있다고 생각했지만 구체적인 내용은 알 수 없었습니다.누군가에게 물고기를 주는 것이 아니라 낚시를 가르치는 정신으로, 저는 그것을 조사하고 알아내기 위해 다음과 같이 했습니다(Python 세션의 C&P).

>>> class Foo(object):
...     @staticmethod
...     def foo():
...         return 3
...     global z
...     z = foo

>>> z
<staticmethod object at 0x0000000002E40558>
>>> Foo.foo
<function foo at 0x0000000002E3CBA8>
>>> dir(z)
['__class__', '__delattr__', '__doc__', '__format__', '__func__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
>>> z.__func__
<function foo at 0x0000000002E3CBA8>

인터랙티브 세션에서의 유사한 종류의 파고들기(dir매우 도움이 됩니다.)는 종종 이러한 종류의 질문을 매우 빠르게 해결할 수 있습니다.

제가 선호하는 방법은 다음과 같습니다.

class Klass(object):

    @staticmethod
    def stat_func():
        return 42

    _ANS = stat_func.__func__()

    def method(self):
        return self.__class__.stat_func() + self.__class__._ANS

나는 이 해결책을 더 선호한다.Klass.stat_func, DRY 원리 때문입니다.Python 3에 새로운 기능이 있는 이유를 상기시킵니다.

그러나 다른 항목에는 동의합니다. 보통 모듈 수준 함수를 정의하는 것이 가장 좋습니다.

예를 들어@staticmethod함수, 재귀가 그다지 좋아 보이지 않을 수 있습니다(콜을 통해 DRY 원칙을 깨야 합니다).Klass.stat_func안에서.Klass.stat_func)에 대한 참조가 없기 때문입니다.selfinside static 메서드모듈 레벨 기능을 사용하면 모든 것이 정상으로 보입니다.

이는 static 메서드가 디스크립터이기 때문에 디스크립터 프로토콜을 실행하고 진정한 콜 가능 여부를 얻기 위해 클래스 레벨 속성 페치가 필요합니다.

소스 코드:

클래스에서 호출할 수 있습니다(예:C.f()또는 인스턴스(예:C().f()클래스 이외에는 인스턴스는 무시됩니다.

단, 정의 중에는 클래스 내부에서 직접 액세스 할 수 없습니다.

하지만 한 해설자가 언급했듯이, 이것은 사실 "피토닉" 디자인이 전혀 아닙니다.대신 모듈 수준 함수를 사용하십시오.

클래스 정의 후에 클래스 속성을 삽입하는 것은 어떻습니까?

class Klass(object):

    @staticmethod  # use as decorator
    def stat_func():
        return 42

    def method(self):
        ret = Klass.stat_func()
        return ret

Klass._ANS = Klass.stat_func()  # inject the class attribute with static method value

이솔솔 은떻? ??? 떻?? of of of of of of of of of of of of of of of of of of of 하지 않는다.@staticmethod데코데StaticMethod는 StaticMethod를 사용합니다.

class Klass(object):

    class StaticMethod:
        @staticmethod  # use as decorator
        def _stat_func():
            return 42

    _ANS = StaticMethod._stat_func()  # call the staticmethod

    def method(self):
        ret = self.StaticMethod._stat_func() + Klass._ANS
        return ret

"핵심 문제"가 함수를 사용하여 클래스 변수를 할당하는 경우, 대안으로 메타클래스를 사용하는 것이 있습니다("Annoying" 및 "Magical"이며, 정적 메서드가 클래스 내에서 호출 가능해야 한다는 데 동의합니다만, 안타깝게도 그렇지 않습니다).이렇게 하면 동작을 독립형 함수로 리팩터링할 수 있어 클래스를 복잡하게 만들지 않습니다.

class KlassMetaClass(type(object)):
    @staticmethod
    def _stat_func():
        return 42

    def __new__(cls, clsname, bases, attrs):
        # Call the __new__ method from the Object metaclass
        super_new = super().__new__(cls, clsname, bases, attrs)
        # Modify class variable "_ANS"
        super_new._ANS = cls._stat_func()
        return super_new

class Klass(object, metaclass=KlassMetaClass):
    """
    Class that will have class variables set pseudo-dynamically by the metaclass
    """
    pass

print(Klass._ANS) # prints 42

"실제 세계"에서 이 대안을 사용하는 것은 문제가 될 수 있다.저는 장고 수업에서 클래스 변수를 무시하기 위해 그것을 사용해야 했지만, 다른 상황에서는 다른 답변의 대안 중 하나를 선택하는 것이 더 나을 수도 있습니다.

언급URL : https://stackoverflow.com/questions/12718187/calling-class-staticmethod-within-the-class-body