pycharm이 메소드를 정적으로 변경하도록 제안하는 이유


154

새로운 pycharm 릴리스 (3.1.3 커뮤니티 에디션)에서는 현재 객체의 상태에서 작동하지 않는 메소드를 정적으로 변환 할 것을 제안합니다.

여기에 이미지 설명을 입력하십시오

그 이유는 무엇입니까? 어떤 종류의 마이크로 성능 (또는 메모리) 최적화?


3
"more ..."를 클릭 했습니까? self메소드 내부의 아무 곳이나 참조하십니까 ? (질문이 실제로 "PyCharm의 디자이너가 왜 이런 식으로 디자인 했는가? 그렇게 질문하지 말아야한다 ...")
Wooble

7
@ Wooo : return 1메소드의 단일 라인 구현이 있습니다. "More"는 유용한 정보를 포함하지 않습니다
zerkms

답변:


189

PyCharm 은 정적 메소드를 갖고 싶었지만 " @staticmethod데코레이터를 사용하여"정적으로 선언하는 것을 잊어 버렸다고 생각합니다 .

PyCharm은 메소드가 본문에서 사용 self 되지 않으므로 실제로 클래스 인스턴스를 변경 하지 않기 때문에이를 제안 합니다 . 따라서 메소드는 정적 일 수 있습니다. 즉, 클래스 인스턴스를 전달하지 않거나 클래스 인스턴스를 만들지 않고도 호출 할 수 있습니다.


4
많은 사람들이이 맛 반응으로 대답했습니다. 그래도 정적 메소드가 아니라는 것을 알고 있다면 "throw NotImplementedError"를 포함 시키면 완료하지 않고는 사용하지 않아야합니다.
Richard Green

1
정적 메소드를 원하지 않거나 상태를 변경하지 않기 때문에 PyCharm의 경고가 정당하지 않은 경우가 있습니다. 반면에, 방법이 아직 구현되지 않은 경우 항상을 올리는 것이 좋습니다 NotImplementedError.
jolvi

3
내 기본 구현은 상수를 반환하지만 하위 클래스는에 따라 값을 반환 할 수 self있습니다. 이 경우 경고는 무시할 수 있으며로 표시합니다 # noinspection PyMethodMayBeStatic. IntelliJ IDEA가이 경고에 대한 상황에 맞는 메뉴에이 비활성화 주석을 추가하는 기능을 제공하지 않는 것은 안타깝습니다.
Alfe

PyCharm 환경 설정에서이 PyCharm 검사의 심각도를 "경고"에서 "강조 표시 없음, 수정 만"으로 변경하는 것이 좋습니다. (그것은 나를 위해 많은 오탐을 생산하고 있습니다.)
maciek

51

@jolvi, @ArundasR 및 기타와 함께 경고를 사용하지 않는 멤버 함수에서 경고가 발생합니다 self.

PyCharm이 잘못되었다고 확신하는 경우, 함수가해서는 안되며 @staticmethod경고가 0이 아닌 경우 두 가지 방법으로 벗어날 수 있습니다.

해결 방법 # 1

def bar(self):
    self.is_not_used()
    doing_something_without_self()

def is_not_used(self):
    pass

해결 방법 # 2 [감사합니다 @ DavidPärsson ]

# noinspection PyMethodMayBeStatic
def bar(self):
    doing_something_without_self()

내가 가지고있는 응용 프로그램 (@staticmethod를 사용할 수없는 이유)은 프로토콜 하위 유형 필드에 응답하기위한 핸들러 함수 테이블을 만드는 것이 었습니다. 모든 핸들러는 동일한 형태의 코스 여야합니다 (정적 또는 비 정적). 그러나 일부는 인스턴스와 관련이 없습니다. 그 정적을 만들면 "TypeError : 'staticmethod'개체를 호출 할 수 없습니다"라는 메시지가 나타납니다.

OP의 consternation을 지원하여 가능한 한 정적 메소드를 추가 할 것을 제안하며 원칙에 위배됩니다. 정적 메소드를 추가 할 것을 제안하고 나중에 코드를 더 제한적으로 만드는 것이 더 쉬운 것보다 더 쉽다 instance.f () 대신 class.f ()를 호출하십시오.

이 경고가 존재하는 이유를 추측합니다.

  • 그것은 StaticMethod를 알립니다 . 개발자가 의도 한 것을 인식하게합니다.
  • @JohnWorrall의 지적대로, 실수로 자신이 빠져 나갔을 때주의를 기울입니다. 기능에서 입니다.
  • 그것은 객체 모델을 다시 생각하게하는 신호입니다. 함수 가이 클래스에 전혀 속하지 않을 수도 있습니다.

1
"메소드를 정적으로 만드는 것은 지금 덜 제한적이다"--- 전혀 그렇지 않다. 예 : 다형성 방법
zerkms

마지막 요점은 "반드시 기능 일 때 왜 메소드로 만드는가?"라고 반복해서 생각합니다. 실제로 인스턴스를 필요로하는 것을 일부 측면을 다루는 구조적인 것과 분리하십시오. 그런 다음 쉽게 개별 모듈로 세분화 할 수 있습니다.
dhill

@dhill 규칙은 합리적인 예외를 생각할 때까지 아름다운 것들입니다. 콜백 목록 중 하나를 설명했습니다.
Bob Stein

7
# noinspection PyMethodMayBeStatic메소드 또는 클래스 위에 추가 하면 경고가 표시되지 않으며 빈 메소드를 호출하는 것보다 낫습니다.
David Pärsson

1
@Talha : self는 Python3에서 전혀 제거되지 않습니다.
Junuxx

12

이 경고의 이유는 Pycharm의 구성이라고 생각합니다. Editor-> Inspection에서 선택 사항 이 정적 일 수 있음을 선택 취소 할 수 있습니다.


12
내 질문은 왜 그런 검사가 존재하는지였습니다. 스위치를 끌 수 있음을 이해합니다. 죄송합니다. 답변이 아닙니다.
zerkms 2016 년

9

나는 여기에 주어진 대답에 동의합니다 (방법은 사용하지 않으므로 self장식 할 수 있습니다 @staticmethod).

클래스 내 정적 메서드 대신 최상위 함수로 메서드를 이동하고 싶을 수도 있습니다. 자세한 내용은이 질문과 허용되는 답변을 참조하십시오 : python-정적 메소드 또는 최상위 함수를 사용해야합니까

메서드를 최상위 함수로 옮기면 PyCharm 경고도 수정됩니다.


정말 유용한 답변-아마도 PyCharm은 경고의 이름을 '방법은 정적이거나 최상위 기능 일 수 있습니다'로 바꾸어야합니다. 메소드를 리팩토링 할 때 pycharm은 self매개 변수가 아닌 경우 정적 메소드가 아닌 최상위 함수를 작성합니다 .
Suzana

데코레이터를 언급 한 @tlo +1 사용하지 않는 self최상위 클래스가있는 클래스가 있지만이 메소드가 수행하는 작업을 볼 때 논리적으로 느껴지지 않습니다. 실제로 해당 클래스에서 생성 된 인스턴스에 대한 작은 도우미 메서드입니다. 따라서 코드를 논리적으로 구성하려면 데코레이터가 완벽한 솔루션입니다.
kasimir

7

클래스 메소드를 정적 메소드로 정의하면 다음과 같은 장점이 있습니다.

  • 클래스 이름을 사용하여 메소드를 호출 할 수 있으며 인스턴스화 할 필요가 없습니다.

남아있는 장점은 아마도 존재하지 않을 것입니다 :

  • 조금 더 빨리 달릴지도 모른다
  • 약간의 메모리를 절약

네. 그러나 문제는-정적 방법으로 사용하지 않는 것입니다. 그렇지 않으면 이미 정적입니다. 따라서 PyCharm은 정당한 이유없이 (?) 조언합니다. "나머지 이점은 아마도 존재하지 않는다면 아마도 한계가 있습니다"--- 맞아요. 이 사건은 그러나 만약 - 그것은 PyCharm에서 바보 같은 충고
zerkms

1
@ zerkms 이것은 매력적인 인스턴스와 함께하는 방법입니다 :-)
Jan Vlcinsky

2
정적 방법은 좋은 소프트웨어를 구축하는 데있어 적입니다. 그들은 많은 원칙을 무효화하므로 bit더 빨리 실행하는 것이 중요 하지 않습니다 (두 경우 모두 램에서 빠르게 실행되기 때문에). 이제 컴퓨터에는 bunch메모리가 있으므로 더 이상 문제가되지 않습니다. 또한 첫 번째 생각에 주목하십시오 : 그것은 객체 지향적 인 것이 아닌 절차 적 행동입니다.
AmirHossein

4

당신이 언급하지 않았기 때문에 self에서 bar메소드 본문이 경우, PyCharm는 요구하고 있습니다 확인하고 싶었습니다 bar정적. Java와 같은 다른 프로그래밍 언어에서는 정적 메소드를 선언해야하는 분명한 이유가 있습니다. 파이썬에서 정적 메소드 (AFIK)의 유일한 장점은 클래스의 인스턴스없이 호출 할 수 있다는 것입니다. 그러나 이것이 유일한 이유라면 최상위 기능을 사용하는 것이 좋습니다 . .

요컨대, 나는 그것이 왜 거기 있는지 백퍼센트 확실하지 않습니다. 나는 그들이 곧 릴리스에서 그것을 제거 할 것이라고 추측하고있다.


3

이 오류 메시지는 테스트 예제 플레이어를 사용하여 실수로 함수를 작성했음을 깨닫지 못했기 때문에 많은 도움이되었습니다.

my_player.attributes[item] 

올바른 방법 대신

self.attributes[item]

1

약간 지저분 할 수도 있지만 때로는 액세스 할 필요는 self없지만 메소드를 클래스에 유지하고 싶지는 않습니다. 정적 것이 좋습니다. 또는보기 흉한 데코레이터를 추가하지 않으려 고합니다. 해당 상황에 대한 몇 가지 잠재적 해결 방법이 있습니다.

메소드에 부작용 만 있고 리턴되는 것에 신경 쓰지 않는 경우 :

def bar(self):
    doing_something_without_self()
    return self

반환 값이 필요한 경우 :

def bar(self):
    result = doing_something_without_self()
    if self:
        return result

이제 메소드가을 사용 self하고 있으며 경고가 사라집니다!


0

파이썬이 none 정적 메소드를 호출 할 때 (@staticmethod를 추가하지 않음) 첫 번째 인수로 self를 전달하기 때문에 Pycharm이 경고로 경고하는 이유. Pycharm은 그것을 알고 있습니다.

예:

class T:
    def test():
        print "i am a normal method!"

t = T()
t.test()
output:
Traceback (most recent call last):
  File "F:/Workspace/test_script/test.py", line 28, in <module>
    T().test()
TypeError: test() takes no arguments (1 given)

나는 Java에서 왔으며 Java에서 "self"는 "this"라고 불리며 클래스 메소드에서 인수로 self (또는 this)를 쓸 필요가 없습니다. 메소드 내부에서 필요에 따라 self를 호출 할 수 있습니다. 그러나 파이썬은 "메소드"를 메서드 인수로 전달해야합니다.

이것을 이해하면 @BobStein 답변으로 해결 방법이 필요하지 않습니다.


그것은 통과 self무엇 때문에?
zerkms

@zerkms '@staticmethod'가 '자기'를 통과하지 못함
Junyu Wu

방금 당신에게 인용했습니다 : "Python은 첫 번째 주장으로 자아를 전달할 것입니다 ... Pycharm은 그것을 알고 있습니다." 그래서 무엇? Pycharm은 그것을 알고 있습니다. 방법을 표시하는 이유는 무엇입니까?
zerkms

Pycharm은 첫 번째 방법 매개 변수가 "자체"가 아닐 수 있다고 생각하기 때문에 @zerkms. 일반적으로 ppl은 메소드 매개 변수를 설계하지 않으며 절대 사용하지 않습니다. Pycharm은 정적 메소드를 작성한다고 생각하고 첫 번째 매개 변수가 "자체"가 아님을 인식하지 못하므로 기본적으로 경고를 표시합니다. 이 혼란은 프로그래밍 언어 디자인으로 인해 발생했습니다. 혼동을 피하기 위해 프로그래밍 디자인을 따르고 (좋은 패턴이 아닌 것 같더라도) "정적 방법"을 추가하는 것이 좋습니다. "자체"를 추가하면 원하는 경우 절대 사용하지 않아도됩니다. 내가 말하는 것은 프로그래밍 디자인을 이해함으로써 다른 의견입니다.
Junyu Wu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.