Methode von nicht-instanzierter Klasse aufrufen

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
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Freitag 5. Mai 2006, 11:40

Habe eine Klasse "foo". Die braucht ein Argument "mode", dass von sys.argv[1] kommt. Ist kein sys.argv[1] gegeben, soll die Methode "usage()" aufgerufen werden, obwohl noch keine Instanz von "foo" vorhanden ist:

Code: Alles auswählen

import sys

class foo:
    # constructor
    def __init__(self, mode):
        print mode
    # usage
    def usage(self):
        print """
        foo.bar
        """

if __name__ == "__main__":
    if not len(sys.argv) > 1:
        foo.usage();
    else:
        foo(sys.argv[1])
Fehlermeldung:
cmd hat geschrieben:Traceback (most recent call last):
File "pyshell.py", line 21, in ?
XmlRpcShell.usage();
TypeError: unbound method usage() must be called with XmlRpcShell instance as fi
rst argument (got nothing instead)
In PHP kann man so auf die Methode einer nicht-instanzierten Klasse zugreifen (Kurzform):
PHP hat geschrieben:<?php
class foo() {
function usage() {
echo ("foo.bar");
}
}

// no instance yet, but method is callable:
foo::usage();
?>
Wie geht das in Python?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Freitag 5. Mai 2006, 11:48

Hi droptix!

Die Funktion "usage" zeigt eine Meldung an, die nur dann wichtig ist,
wenn das Modul **direkt** aufgerufen wurde. Wenn das Modul
importiert wurde, dann braucht es die Funktion "usage" nicht. Warum
willst du sie dann unbedingt in der Klasse haben?

Code: Alles auswählen

import sys

# usage
def usage():
    print """
    foo.bar
    """

class foo:
    # constructor
    def __init__(self, mode):
        print mode

if __name__ == "__main__":
    if not len(sys.argv) > 1:
        usage();
    else:
        foo(sys.argv[1])
Es gibt zwar auch die Möglichkeit, die Funktion mit @staticmethod zu
dekorieren, das ist aber in deinem Fall nicht angebracht, da "usage" ja
sowiso nicht in die Klasse passt.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Freitag 5. Mai 2006, 12:02

Na weil usage() zum Programm gehört. Tut nix weiter als die Syntax des Programms auszugeben... Angenommen, mein Programm verlangt

foo.py bar

Dann ist zwar sys.argv[1] gegeben, aber "bar" ist vielleicht kein gültiger Parameter für die Klasse. Also wird später der Constructor den Parameter "mode" überprüfen und bei falscher Syntax/falschem Wert ebenfalls usage() aufrufen. Also gehört usage() direkt zum Programm und sollte in der Klasse sein.

Ich kann natürlich auch das hier machen und dann mode prüfen:

Code: Alles auswählen

if __name__ == "__main__":
    foo(sys.argv[1:])
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Freitag 5. Mai 2006, 12:38

Nicht direkt eine Antwort auf deine Frage, aber vielleicht solltest du dir mal das Modul optparse ansehen?
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 5. Mai 2006, 13:20

Rebecca hat geschrieben:optparse
Jup, hab erst gestern damit was gemacht:

https://opensvn.csie.org/traccgi/PyLuci ... fs.py#L172

Noch ein Beispiel von Leonidas:
http://www.python-forum.de/post-16397.html#16397

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Freitag 5. Mai 2006, 13:29

Hat denn keiner eine Antwort für den armen droptix?

Code: Alles auswählen

>>> class C(object):
...     @staticmethod
...     def usage():
...             print "Hello World"
...
>>> C.usage()
Hello World
//Edit: sorry, mein Fehler. Gerold hat staticmethod schon erwähnt
TUFKAB – the user formerly known as blackbird
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 5. Mai 2006, 13:54

droptix hat geschrieben:Habe eine Klasse "foo". Die braucht ein Argument "mode", dass von sys.argv[1] kommt. Ist kein sys.argv[1] gegeben, soll die Methode "usage()" aufgerufen werden, obwohl noch keine Instanz von "foo" vorhanden ist:
Warum machst du nicht mode = None, wenn sys.argv[1] nicht da ist und reagierst in einer Klasse dementsprechend...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten