Was hat der Hinweis method_xyz may be 'static' zu bedeuten ?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

Hallo !

verstehe schon wieder was nicht ! :oops:

Folgender Auschnitt:

Code: Alles auswählen

import sys
from PyQt4 import QtGui
import editdata as ed

class MainWindow(QtGui.QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.edit_widget = None
        ...
        
    def new_button(self):
        self.edit_widget = ed.EditData()

    def change_button(self):
        print('Change')
        ...
    ...
Bei change_button() erhalte ich den freundlichen Hinweis von PyCharm:
Method 'change_button' may be 'static'
This inspection detects any methods which may safely be made static.
Bei new_button() aber nicht ! :?

Ich sehe da keinen Unterschied. :roll: Was bedeutet denn das "may safely be made static" ?

Freundliche Grüße
mephisto_online
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@mephisto_online: Du verwendest »self« nicht.
BlackJack

Ergänzend: Dann sollte man überlegen warum das überhaupt eine Methode auf dem Objekt ist und es entweder aus der Klasse heraus nehmen und als die Funktion definieren die es eigentlich ist, oder mit `staticmethod()` eine statische Methode daraus machen.
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

Sirius3 hat geschrieben:Du verwendest »self« nicht.
Dieser Unterschied ist mir auch schon aufgefallen. D.h. ich sollte also alle Objekte, mit denen ich in "self" etwas anstellen möchte, erst in den Kontext von "self" bringen, bevor ich sie benutze ? Wie könnte ich denn das mit print() machen, ohne diese Message zu bekommen ?
BlackJack hat geschrieben:... Dann sollte man überlegen warum das überhaupt eine Methode auf dem Objekt ist...
OK, die Methode macht so natürlich keinen Sinn ! Ich hatte damit nur die Slots getestet. Und dafür muss sie im Kontext der Klasse sein. Oder nicht ?
BlackJack hat geschrieben:...und es entweder aus der Klasse heraus nehmen und als die Funktion definieren die es eigentlich ist
Genau da habe ich noch Verständnislücken. Welche Kontexte gibt es in Python: den Klassen/Klassen-Objekt-Kontext und den Package-Kontext (wo die main() steht), ich weiss nicht ob ich es jetzt richtig bezeichnet habe. Und wie komme ich z.B. aus einem Klassen-Objekt-Kontext an den Package-Kontext ?
BlackJack hat geschrieben: ...oder mit `staticmethod()` eine statische Methode daraus machen.
Ist `staticmethod()` vielleicht das Zauberwort, welches den Package-Kontext meint ? Da ist ja eigentlich alles static...

Viele Grüße
mephisto-online

EDIT:
Habe es gerade gefunden. Nach staticmethod hatte ich noch nicht gesucht, weil ich bei Python mit "static" nicht gerechnet habe. :oops:

Code: Alles auswählen

class MyClass(object):
    @staticmethod
    def the_static_method(x):
        print x

MyClass.the_static_method(2) # outputs 2
Quelle: http://stackoverflow.com/questions/7359 ... -in-python
BlackJack

@mephisto-online: Wenn die Methode keinen Sinn macht weil sie nur zum Testen von Slots ist, dann brauchst Du auf den Hinweis von der IDE ja auch nicht achten, denn in einer tatsächlich sinnvollen Methode würdest Du ja nicht nur etwas mit `print()` ausgeben.

Ein „slot” muss nicht zwingend eine Methode sein, da geht jedes aufrufbare Objekt, also zum Beispiel auch Funktionen.

Ich denke mal statt Package meinst Du Modul weil das Beispiel kein Package verwendet beziehungsweise ein Package letztendlich ja auch nur eine spezielle Art von Modul ist. In einer Klasse und in Methoden kannst Du genau wie in Funktionen auch alles aus dem Modulnamensraum benutzen. Wenn ein Namen in einer Funktion oder Methode nicht lokal ist, dann wird er in den lexikalisch umgebenden Namensräumen (das meinst Du wahrscheinlich mit Kontext) gesucht. Also erst in umgebendenen Funktionen/Methoden falls man die verschachtelt hat, dann auf Modulebene, und dann in den eingebauten Funktionen, dem `__builtin__`-Modul.

`staticmethod()` ist kein Zauberwort sondern eine Funktion. Die ist, genau wie `classmethod()` in den eingebauten Funktionen enthalten. Beide kann man mit der Dekorarorsyntax verwenden.

Code: Alles auswählen

    @staticmethod
    def change_button():
        print('Change')
Das sollte die IDE auch beruhigen. Und der Leser weiss dann das es kein Versehen ist, wenn `self` nicht verwendet wird, sondern das dort absichtlich eine Funktion auf der Klasse definiert wurde.

Zum Bearbeiten-Fenster: Hast Du Dir Gedanken darüber gemacht was passieren soll wenn der Benutzer die Schaltfläche noch einmal betätigt? Wenn auch mehrere Fenster gleichzeitig offen sein dürfen, funktioniert das *so* nicht. Und ansonsten wäre ein modaler Dialog vielleicht die ”natürlichere” Lösung.
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

BlackJack hat geschrieben:Ein „slot” muss nicht zwingend eine Methode sein, da geht jedes aufrufbare Objekt, also zum Beispiel auch Funktionen.
"aufrufbares Objekt", was ist genau damit gemeint ?
BlackJack hat geschrieben:Ich denke mal statt Package meinst Du Modul weil das Beispiel kein Package verwendet beziehungsweise ein Package letztendlich ja auch nur eine spezielle Art von Modul ist.

Ja, ich meinte, richtig bezeichnet, Modul (danke). Nach dem genauen Unterschied Modul/Package (und auch Methode/Funktion) muss ich wohl noch mal googlen. So ganz ist mir das noch nicht klar. (Hat das vielleicht was mir dem Return-Wert zu tun?)
BlackJack hat geschrieben:In einer Klasse und in Methoden kannst Du genau wie in Funktionen auch alles aus dem Modulnamensraum benutzen.
Sind das die von mir zwar registrierten aber noch nicht genau betrachteten "namespace"s ? Aber wie greife ich denn aus dem Namensraum einer Klasse auf ein Objekt im Modulnamensraum zu ?
BlackJack hat geschrieben:Wenn ein Namen in einer Funktion oder Methode nicht lokal ist, dann wird er in den lexikalisch umgebenden Namensräumen (das meinst Du wahrscheinlich mit Kontext) gesucht.
Ja, so ungefähr. Kontext sagt man aber wohl nicht bei Python. Allerdings verstehe ich "lexikalisch umgebende Namensräume" nicht so ganz genau.
BlackJack hat geschrieben:Also erst in umgebendenen Funktionen/Methoden falls man die verschachtelt hat, dann auf Modulebene, und dann in den eingebauten Funktionen, dem `__builtin__`-Modul.
Das ist sehr exakt beschrieben, danke !
BlackJack hat geschrieben:`staticmethod()` ist kein Zauberwort sondern eine Funktion. Die ist, genau wie `classmethod()` in den eingebauten Funktionen enthalten.
Klar, in Python gibt es keine Zauberwörter :oops: Mit dem `__builtin__`- Modul muss ich mich also auch mal genau beschäftigen. Es ist sehr gut, dass Du mir zeigst, welche Zusammenhänge und Begriffe ich noch mal nachlesen muss.
BlackJack hat geschrieben:Beide kann man mit der Dekorarorsyntax verwenden.

Code: Alles auswählen

    @staticmethod
Es gibt also eine Dekoratorsyntax und eine Funktions-Syntax für ein und die selbe Funktion ?
BlackJack hat geschrieben:Das sollte die IDE auch beruhigen. Und der Leser weiss dann das es kein Versehen ist, wenn `self` nicht verwendet wird, sondern das dort absichtlich eine Funktion auf der Klasse definiert wurde.
Danke, super erklärt !
BlackJack hat geschrieben:Hast Du Dir Gedanken darüber gemacht was passieren soll wenn der Benutzer die Schaltfläche noch einmal betätigt? Wenn auch mehrere Fenster gleichzeitig offen sein dürfen, funktioniert das *so* nicht.
Nein, habe ich noch nicht. Man braucht das Bearbeiten-Fenster nur einmal (es werden nicht mehrere Datensätze auf einmal bearbeitet). Aber da hast Du Recht, den Button muss ich deaktivieren, wenn das Fenster geöffnet ist, sonst gibt es wohl einen fatalen Fehler.
BlackJack hat geschrieben:Und ansonsten wäre ein modaler Dialog vielleicht die ”natürlichere” Lösung.
Was ist ein "modaler Dialog" ? :?

Viele Grüße
mephisto-online
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

mephisto-online hat geschrieben:"aufrufbares Objekt", was ist genau damit gemeint ?
Alles, was du am Ende mit "(...)" aufrufen kannst. Funktionen, Klassen, also alles, was eine "__call__"-Methode beseitzt. Such einfach mal nach "python callable".
mephisto-online hat geschrieben:Nach dem genauen Unterschied Modul/Package (und auch Methode/Funktion) muss ich wohl noch mal googlen. So ganz ist mir das noch nicht klar. (Hat das vielleicht was mir dem Return-Wert zu tun?)
Eine Methode ist eine Funktion, welche zu einer Klasse gehört:

Code: Alles auswählen

def function():
    ....

class Spam(object):
    def method(...):
        ...
mephisto-online hat geschrieben:]Sind das die von mir zwar registrierten aber noch nicht genau betrachteten "namespace"s ? Aber wie greife ich denn aus dem Namensraum einer Klasse auf ein Objekt im Modulnamensraum zu ?
Das machst du schon ständig:

Code: Alles auswählen

def ham():
    print "ham"

class Eggs(object):
    def foo(self):
        ham()
Hier greifst du in "foo" auf den Modulnamensraum zu, indem du "ham" aufrufst.
mephisto-online hat geschrieben:Allerdings verstehe ich "lexikalisch umgebende Namensräume" nicht so ganz genau.
Das ist die Suchreihenfolge, welche BlackJack beschrieben hat:
BlackJack hat geschrieben:Also erst in umgebendenen Funktionen/Methoden falls man die verschachtelt hat, dann auf Modulebene, und dann in den eingebauten Funktionen, dem `__builtin__`-Modul.
mephisto-online hat geschrieben:Es gibt also eine Dekoratorsyntax und eine Funktions-Syntax für ein und die selbe Funktion ?
Ich verlinke da einfach mal auf meine Erklärung .
mephisto-online hat geschrieben:Was ist ein "modaler Dialog" ?
Ein Dialog, welcher als einziges Fenster der Anwendung den Fokus haben kann. Du kannst also nicht gleichzeitig zwei Fenster öffnen und parallel benutzen. Bei der Gelegenheit ein kleiner Hinweis: die Suchmaschine deiner Wahl liefert dir dazu jede Menge Informationen ;-)
Das Leben ist wie ein Tennisball.
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

Hallo,

"aufrufbares Objekt":
EyDu hat geschrieben:Alles, was du am Ende mit "(...)" aufrufen kannst. Funktionen, Klassen, also alles, was eine "__call__"-Methode beseitzt. Such einfach mal nach "python callable".
Ok. Verstanden !
EyDu hat geschrieben:Eine Methode ist eine Funktion, welche zu einer Klasse gehört
Auch geklärt! Hat nichts mit Return zu tun. Also eine "def" in einer Klasse... Danke !
EyDu hat geschrieben:Das machst du schon ständig:

Code: Alles auswählen

def ham():
    print "ham"

class Eggs(object):
    def foo(self):
        ham()
Hier greifst du in "foo" auf den Modulnamensraum zu, indem du "ham" aufrufst.
Super ! Auch definitiv geklärt !

"lexikalisch umgebende Namensräume:
EyDu hat geschrieben:Das ist die Suchreihenfolge
Kurz und knapp, so wie ich es verstehe, Danke ! Geklärt !
EyDu hat geschrieben:Ich verlinke da einfach mal auf meine Erklärung .
Ok, im Prinzip auch verstanden, Ist aber schon etas gewöhnungsbedürftiger. Muss ich erst mal ausprobieren. Auch danke !

"modaler Dialog":
EyDu hat geschrieben:Ein Dialog, welcher als einziges Fenster der Anwendung den Fokus haben kann.
Super auf den Punkt gebracht ! Ebenfalls sofort kapiert !
EyDu hat geschrieben:Bei der Gelegenheit ein kleiner Hinweis: die Suchmaschine deiner Wahl liefert dir dazu jede Menge Informationen ;-)
Danke für den Hinweis ! Ich sagte schon, dass mir einfach die Begrifflichkeiten, nach denen ich suchen muss, noch nicht ganz klar waren. Da habt Ihr mich jetzt erst richtig eingenordet. Jede Sprache ist halt eine eigene Welt, in der man erst mal die korrekte Terminologie drauf haben muss, um auch fündig zu werden. Verstehen ist das Eine, es benennen zu können, das Andere.

Aber Ihr habt mich heute wirklich meilenweit weiter gebracht !

Viele Grüße
mephisto-online
Antworten