Class Methods

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
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Hi ihrs,

Etwas das ich an Python bisher noch nicht verstanden habe ist wie ich "Klassen Methoden" definieren kann. So etwas in der Art:

Code: Alles auswählen

class Foo(object):
    def Bar():
        print "Foobar"
Foo.Bar()
Das Funktionier jedoch nicht:

Code: Alles auswählen

TypeError: unbound method Bar() must be called with Foo instance as first argument (got nothing instead)
Ist das in Python überhaupt möglich? Wenn ja, wie?
BlackJack

Das was Du möchtest heisst in Python `staticmethod`:

Code: Alles auswählen

class Spam:
    @staticmethod
    feep():
        pass
Klassenmethoden gibt's auch (`classmethod`), die bekommen als erstes Argument "automagisch" die Klasse übergeben anstatt der Instanz wie bei normalen Methoden.
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Vielen dank, war genau was ich gesucht habe.
Ene Uran
User
Beiträge: 125
Registriert: Sonntag 17. September 2006, 20:14
Wohnort: Hollywood

Normalerweise wird eine Klasse so zusammengebastelt:

Code: Alles auswählen

class Foo(object):
    # this is the class constructor
    def __init__(self):
        pass
    
    def Bar(self):
        print "Foobar"

# instance of class
foo1 = Foo()
foo1.Bar()   # --> Foobar
# oder ...
Foo().Bar()  # --> Foobar
Die Instanz gibt der Klasse Macht!

Bist Du wirklich faul, dann gehts auch so:

Code: Alles auswählen

class Foo(object):
    @staticmethod
    def Bar():
        print "Foobar"
        
Foo.Bar()  # --> Foobar
Atomkraftwerkaktienbesitzer
BlackJack

Das hat nicht zwingend was mit "faul" zu tun. Es macht zum Beispiel Sinn Factory-Funktionen, die Objekte vom Typ der Klasse liefern, als `staticmethod` oder `classmethod` an die Klasse zu binden.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

@Ene Uran: Staticmethoden != "Instanzmethoden".

Ein Instanzmethode kann nur über die Instanz der Klasse benutzt werden.
``Foo().Bar()`` <- ``Foo()'' (Man achte auf die Klammern) erzeugt ein Objekt (Instanz) der Klasse ``Foo``. ``.Bar()`` ruft die "Instanzmethoden" für die eben erzeugt Instanz auf.

``Foo.Bar()`` <- Ruft die Staticmethoden der Klasse ``Foo`` auf.

Das schöne an statischen Methoden ist, das man eine Klasse als Namencpace benutzen kann (Die *nicht* zur instanziierung gedacht ist!) um zusammengehöriges in besagten zu kapseln. Bei Attributen ist das trivial, da man sie als Klassenattribute definiert:

Code: Alles auswählen

class Foo(object):
    attr1 = None
    attr2 = None
print Foo.attr1
Bei Methoden wird es unschön wenn sie als Instanzmethoden defineirt werden, da man immer erst eine Instanz bilden muss um die Methode aufzurufen: In anderen Worten: Ich muss vor dem Klassennamen eine öffnenden und schließenden Klammer schreiben:

Code: Alles auswählen

class Foo(object):
    attr1 = None
    attr2 = None
    def Bar(self):
        pass
print Foo.attr1
Foo().Bar() # :-[
Hier kommt nun ``@staticmethod`` ins spiel mit dem es nicht notwendig ist die klasse zu instanziieren:

Code: Alles auswählen

class Foo(object):
    attr1 = None
    attr2 = None

    @staticmethod
    def Bar(self):
        pass
print Foo.attr1
Foo.Bar() # :-)
Ich nutze das Feature gelegentlich für Objekte die ein Namenspace, und nicht mehr, sein sollen, in dem Konstanten und statische Methoden als Modifikatoren definiert sind, um alles unter einem Namen zusammenzufassen. So muss ich nicht extra ein Module schreiben um zusammengehöriges in einem Namensraum zusammenzufassen, sondern es langt einfach eine Klasse dafür :)
Antworten