클래스 본문 내에서 클래스 스태틱 메서드를 호출하시겠습니까?
클래스 본문 내에서 정적 메서드를 사용하고 빌트인을 사용하여 정적 메서드를 정의하려고 하면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
'programing' 카테고리의 다른 글
| 목록 항목의 발생 횟수를 계산하려면 어떻게 해야 합니까? (0) | 2022.11.11 |
|---|---|
| PHP 코딩 스타일 반환(스위치/케이스) (0) | 2022.11.11 |
| vuex 돌연변이에 비동기 기능이 없는 이유(어차피 작동하지 않음) (0) | 2022.11.11 |
| 한 줄 명령줄에서 여러 줄 문 실행 (0) | 2022.11.11 |
| PHP에서 PDO로 열린 SQL 연결을 닫아야 합니까? (0) | 2022.11.11 |