Warum schlägt Pycharm vor, die Methode auf statisch zu ändern?

153

Die neue Pycharm-Version (3.1.3 Community Edition) schlägt vor, die Methoden, die mit dem Status des aktuellen Objekts nicht funktionieren, in statische zu konvertieren.

Geben Sie hier die Bildbeschreibung ein

Was ist der praktische Grund dafür? Eine Art von Mikroleistungsoptimierung (-oder-Speicheroptimierung)?

zerkms
quelle
3
Haben Sie auf "mehr ..." geklickt? Verweisen Sie selfirgendwo innerhalb der Methode? (Wenn die Frage wirklich lautet: "Warum haben die Designer von PyCharm es so entworfen ... müssen Sie sie fragen, nicht SO ...)
Wooble
7
@Wooble: Es gibt return 1eine einzeilige Implementierung der Methode. "Mehr" enthält nichts Nützliches
zerkms

Antworten:

186

PyCharm "denkt", dass Sie vielleicht eine statische Methode haben wollten , aber Sie haben vergessen, sie als statisch zu deklarieren (mithilfe des @staticmethodDekorators).

PyCharm schlägt dies vor, da die Methode in ihrem Hauptteil nicht verwendet self wird und daher die Klasseninstanz nicht tatsächlich ändert . Daher kann die Methode statisch sein, dh ohne Übergabe einer Klasseninstanz oder ohne eine Klasseninstanz erstellt zu haben.

jolvi
quelle
4
So viele Leute haben mit dieser Geschmacksantwort geantwortet. Ich würde jedoch hinzufügen, wenn Sie wissen, dass es definitiv keine statische Methode sein wird, fügen Sie einen "throw NotImplementedError" hinzu, während Sie dort sind, um sicherzugehen, dass Sie ihn nicht verwenden, ohne ihn abzuschließen.
Richard Green
1
Es kann Fälle geben, in denen die Warnung von PyCharm nicht gerechtfertigt ist, da wir weder eine statische Methode wünschen noch den Status ändern möchten. Wenn die Methode jedoch noch nicht implementiert ist, scheint es immer eine gute Idee zu sein, a zu erhöhen NotImplementedError.
Jolvi
3
Ich habe den Fall, dass meine Standardimplementierung eine Konstante zurückgibt, aber meine Unterklassen dürfen abhängig davon einen Wert zurückgeben self. In diesem Fall ist die Warnung vernachlässigbar und ich markiere sie mit # noinspection PyMethodMayBeStatic. Es ist schade, dass IntelliJ IDEA nicht anbietet, diesen deaktivierenden Kommentar in die Kontextmenüs für diese Warnung einzufügen.
Alfe
Ich schlage vor, den Schweregrad dieser PyCharm-Inspektion in den PyCharm-Einstellungen von "Warnung" in "Keine Hervorhebung, nur Korrektur" zu ändern. (Es produziert viele Fehlalarme für mich.)
Maciek
50

In Übereinstimmung mit @jolvi, @ArundasR und anderen tritt die Warnung für eine Mitgliedsfunktion auf, die nicht verwendet wird self.

Wenn Sie sicher sind, dass PyCharm falsch ist, dass die Funktion keine sein sollte @staticmethod, und wenn Sie null Warnungen bewerten, können Sie diese auf zwei verschiedene Arten entfernen:

Problemumgehung Nr. 1

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

def is_not_used(self):
    pass

Problemumgehung Nr. 2 [Danke @ DavidPärsson ]

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

Die Anwendung, die ich dafür hatte (der Grund, warum ich @staticmethod nicht verwenden konnte), bestand darin, eine Tabelle mit Handlerfunktionen zum Antworten auf ein Protokoll-Subtyp-Feld zu erstellen. Alle Handler mussten natürlich die gleiche Form haben (statisch oder nicht statisch). Aber einige haben zufällig nichts mit der Instanz gemacht. Wenn ich diese statisch machen würde, würde ich "TypeError: 'staticmethod' Objekt ist nicht aufrufbar" erhalten.

Die Unterstützung der Bestürzung des OP, die vorschlägt, statische Methoden hinzuzufügen, wann immer Sie können, verstößt gegen das Prinzip, dass es einfacher ist, Code später weniger restriktiv zu machen als mehr - eine statische Methode macht sie jetzt weniger restriktiv, da Sie dies können Rufen Sie class.f () anstelle von instance.f () auf.

Vermutungen, warum diese Warnung existiert:

  • Es kündigt statische Methode an . Es macht Entwickler auf etwas aufmerksam, das sie möglicherweise beabsichtigt haben.
  • Wie @ JohnWorrall hervorhebt, wird es Ihre Aufmerksamkeit erregen, wenn das Selbst versehentlich aus der Funktion ausgeschlossen wurde.
  • Es ist ein Hinweis, das Objektmodell zu überdenken. Vielleicht gehört die Funktion überhaupt nicht in diese Klasse.
Bob Stein
quelle
1
"Eine Methode statisch zu machen, macht sie jetzt weniger restriktiv" --- das tut es überhaupt nicht. ZB: polymorphe Methoden
Zerkms
Ich denke, der letzte Punkt muss wiederholt werden: "Warum machst du es zu einer Methode, wenn es eindeutig eine Funktion ist?" Halten Sie die Dinge, die wirklich eine Instanz benötigen, von den strukturellen Dingen getrennt, die sich mit bestimmten Aspekten befassen. Sie können es dann einfach in ein separates Modul unterteilen.
Dhill
@dhill Regeln sind schöne Dinge bis zu dem Tag, an dem Sie sich eine vernünftige Ausnahme ausdenken. Ich habe einen beschrieben, eine Liste von Rückrufen.
Bob Stein
7
Das Hinzufügen # noinspection PyMethodMayBeStaticüber der Methode oder Klasse unterdrückt die Warnung und ist meiner Meinung nach besser als das Aufrufen einer leeren Methode.
David Pärsson
1
@Talha: selfwird in Python3 überhaupt nicht entfernt.
Junuxx
12

Ich denke, dass der Grund für diese Warnung die Konfiguration in Pycharm ist. Sie können die Auswahlmethode unter Editor-> Inspektion möglicherweise statisch deaktivieren

mincom
quelle
12
Meine Frage war, warum es eine solche Inspektion überhaupt gibt. Ich verstehe, ich kann es ausschalten. Entschuldigung, keine Antwort.
Zerkms
8

Ich bin mit den hier gegebenen Antworten einverstanden (Methode verwendet nicht selfund könnte daher mit dekoriert werden@staticmethod ).

Ich möchte hinzufügen, dass Sie die Methode möglicherweise in eine Funktion der obersten Ebene anstelle einer statischen Methode innerhalb einer Klasse verschieben möchten. Einzelheiten finden Sie in dieser Frage und in der akzeptierten Antwort: Python - sollte ich statische Methoden oder Funktionen der obersten Ebene verwenden?

Wenn Sie die Methode auf eine Funktion der obersten Ebene verschieben, wird auch die PyCharm-Warnung behoben.

tlo
quelle
Wirklich hilfreiche Antwort - vielleicht sollte PyCharm die Warnung in "Methode kann statisch oder Funktion der obersten Ebene sein" umbenennen. Beim Umgestalten einer Methode erstellt pycharm eine Funktion der obersten Ebene und ohnehin keine statische Methode, wenn dies selfkein Parameter ist.
Suzana
@tlo +1 für die Erwähnung des Dekorateurs. Ich habe eine Klasse mit einer Methode, die nicht verwendet wird selfund daher auf oberster Ebene sein könnte. Dies ist jedoch nicht logisch, wenn man sich die Funktionsweise dieser Methode ansieht. Auf oberster Ebene würde sie eher wie eine globale Methode aussehen, solange sie es ist Tatsächlich eine kleine Hilfsmethode für Instanzen, die aus dieser Klasse erstellt wurden. Um meinen Code logisch zu organisieren, ist der Dekorateur die perfekte Lösung.
Kasimir
7

Ich kann mir folgende Vorteile vorstellen, wenn eine Klassenmethode als statisch definiert wird:

  • Sie können die Methode nur mit dem Klassennamen aufrufen, ohne sie instanziieren zu müssen.

Die verbleibenden Vorteile sind wahrscheinlich gering, wenn überhaupt vorhanden:

  • könnte etwas schneller laufen
  • Sparen Sie ein bisschen Speicher
Jan Vlcinsky
quelle
Ja. Aber die Sache ist - ich benutze es nicht als statische Methode. Sonst wäre es schon statisch. PyCharm rät daher, dies ohne guten Grund zu tun (?). "verbleibende Vorteile sind wahrscheinlich marginal, wenn überhaupt vorhanden" --- ja, genau. Aber wenn es der Fall ist - es ist ein dummer Rat von PyCharm
zerkms
1
@ Zerkms so geht es mit einigen charmanten Instanzen :-)
Jan Vlcinsky
1
Statische Methoden sind ein Feind beim Erstellen guter Software. Sie machen viele Prinzipien ungültig, so dass es nicht darauf bitankommt, schneller zu laufen (weil sie in beiden Fällen im RAM laufen), und wie Sie wissen, verfügen Computer jetzt über bunchSpeicher, sodass dies kein Problem mehr darstellt. Beachten Sie auch Ihren ersten Gedanken: Das ist ein prozedurales Verhalten, kein objektorientiertes.
AmirHossein
4

Da Sie selfim barMethodenkörper nicht darauf verwiesen haben, fragt PyCharm, ob Sie möglicherweisebar statisch machen wollten . In anderen Programmiersprachen wie Java gibt es offensichtliche Gründe für die Deklaration einer statischen Methode. In Python besteht der einzige wirkliche Vorteil einer statischen Methode (AFIK) darin, sie ohne eine Instanz der Klasse aufrufen zu können. Wenn dies jedoch Ihr einziger Grund ist, ist es wahrscheinlich besser, eine Funktion der obersten Ebene zu verwenden - wie hier angegeben .

Kurz gesagt, ich bin mir nicht hundertprozentig sicher, warum es dort ist. Ich vermute, sie werden es wahrscheinlich in einer kommenden Version entfernen.

Don
quelle
3

Diese Fehlermeldung hat mir nur ein paar geholfen, da ich nicht bemerkt hatte, dass ich meine Funktion versehentlich mit meinem Testbeispiel-Player geschrieben hatte

my_player.attributes[item] 

statt des richtigen Weges

self.attributes[item]
John Worrall
quelle
1

Es mag etwas chaotisch sein, aber manchmal müssen Sie einfach nicht darauf zugreifen self, aber Sie möchten die Methode lieber in der Klasse behalten und nicht statisch machen. Oder Sie möchten einfach vermeiden, ein paar unansehnliche Dekorateure hinzuzufügen. Hier sind einige mögliche Problemumgehungen für diese Situation.

Wenn Ihre Methode nur Nebenwirkungen hat und Sie sich nicht darum kümmern, was sie zurückgibt:

def bar(self):
    doing_something_without_self()
    return self

Wenn Sie den Rückgabewert benötigen:

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

Jetzt wird Ihre Methode verwendet selfund die Warnung verschwindet!

Junuxx
quelle
0

Der Grund, warum Pycharm es als Warnung macht, weil Python sich selbst als erstes Argument beim Aufrufen einer nicht statischen Methode übergibt (nicht @staticmethod hinzufügen). Pycharm weiß es.

Beispiel:

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)

Ich komme aus Java, in Java heißt "self" "this", Sie müssen nicht self (oder this) als Argument in der Klassenmethode schreiben. Sie können sich innerhalb der Methode einfach nach Bedarf selbst aufrufen. Aber Python "muss" sich selbst als Methodenargument übergeben.

Wenn Sie dies verstehen, benötigen Sie keine Problemumgehung als @ BobStein-Antwort.

Junyu Wu
quelle
Es geht selfso was?
Zerkms
@zerkms '@staticmethod' geht nicht an 'self' vorbei
Junyu Wu
Ich habe Sie gerade zitiert: "Python wird sich als erstes Argument übergeben ... Pycharm weiß es." Na und? Pycharm weiß es, ich weiß es. Was ist der Grund, die Methode zu markieren?
Zerkms
@zerkms, weil Pycharm glaubt, dass Ihr erster Methodenparameter möglicherweise nicht das "Selbst" ist. Normalerweise entwirft ppl keinen Methodenparameter und verwendet ihn niemals. Pycharm glaubt, dass Sie eine statische Methode erstellen, und hat nicht erkannt, dass der erste Parameter nicht das "Selbst" ist. Daher wird standardmäßig eine Warnung ausgegeben. Diese Verwirrung wird durch das Design der Programmiersprache verursacht. Ich schlage vor, Sie folgen dem Programmierdesign (auch wenn es kein gutes Muster zu sein scheint) und fügen "staticmethod" hinzu, um Verwirrung zu vermeiden. Es ist völlig in Ordnung, wenn Sie ein "Selbst" hinzufügen und es dann niemals verwenden, wenn Sie es vorziehen. Was ich sage, ist nur eine andere Meinung, wenn man das Programmdesign versteht.
Junyu Wu