Klassen-Methoden auslagern

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
Roque
User
Beiträge: 6
Registriert: Samstag 8. August 2009, 14:49
Wohnort: München

Hi!

Mein Name ist Johannes, ich studiere Informatik und arbeite mich momentan in Python ein.

Da ich ein von mir geschriebenes Programm von C++ in Python übersetzen möchte, bin ich auf ein triviales Problem gestoßen: Wie kann ich Methoden, die innerhalb einer Klasse definiert werden, auslagern?

In meinen bisherigen Quellen wurden alle Methoden innerhalb der Klassen-Definition angegeben (quasi "inline" in C/C++). Wie kann nun eine Methode einer Klasse zugeordnet werden (nur Funktionskopf angeben) und in einem seperaten Modul implementiert werden?

Danke für Eure Hilfe!
Johannes
BlackJack

@Roque: Du kannst einfach die Funkion definieren und dann als Attribut an die Klasse binden.

Das macht man aber in Python nicht. Versuche am besten nicht das Programm 1:1 von C++ zu übersetzen, sondern schreibe echten, idiomatischen Python-Quelltext.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo,

das willst du sicherlich nicht tun. Alles was zu einer Klasse gehört, sollte auch darin stehen. Und keinem Fall sollte eine Klasse über verschiedene Module verteilt werden. Module solltest du nicht als Dateien verstehen, sondern als ein Paket aus zusammengehörender Aufgaben. Daher stehen dort im Normalfall mehr als nur eine Klasse drin.

Wenn dein Code zu unübersichtlich wird, dann liegt es mit sehr großer Wahrscheinlichkeit an einer falschen Aufteilung des Programms. Du solltest daher noch einmal überlegen, ob nicht zu viel Funktionalität in einer Klasse liegt und ob diese nicht besser geteilt werden sollte.

Vielleicht solltest du noch ein wenig erklären, warum du so eine Aufteilung machen möchtest unter Umständen liegt das Problem an einer anderen Stelle.

Viele Grüße,
Sebastian
Das Leben ist wie ein Tennisball.
Roque
User
Beiträge: 6
Registriert: Samstag 8. August 2009, 14:49
Wohnort: München

Hi,

Danke für Eure Antworten!

Meine Frage kam eigentlich nur aus der Gewohnheit heraus. In C++ hab ich zwecks Übersicht meist eine header-Datei für die Klassen-Definition, die .cpp für die main und die .cpps für die verschiedenen Methoden. Deswegen kam einfach die Frage, wie ich das in Python umsetzen kann.

Also wenn ich richtig verstehe werden in Python die Methoden immer inline-deklariert, also direkt in der Klassen-Definition implementiert, oder?

Grüße
Johannes
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Jein: Es gibt in Python kein "inline" und keine separate Deklaration / Definition. Doch ja, das gehört alles in File. Und für gewöhnlich hat man doch größere Übersicht als in C++-Code ;-).

HTH
Christian
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ich meine, wenn es unbedingt sein soll, kann man natürlich auch folgende einfache Hilfsfunktion benutzen:

Code: Alles auswählen

class Foo(object):
    pass

def Foo_bar(self):
    return 1
    
def add_functions_to_classes_as_in_Cpp():
    names_and_values = globals().items()
    classes = dict((n, v) for n, v in names_and_values if isinstance(v, type))
    function = type(add_functions_to_classes_as_in_Cpp)
    for n, v in names_and_values:
        if isinstance(v, function):
            cls_and_n = n.split("_", 1)
            if len(cls_and_n) == 2 and cls_and_n[0] in classes:
                setattr(classes[cls_and_n[0]], cls_and_n[1], v)

add_functions_to_classes_as_in_Cpp()

print Foo().bar()
Stefan
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Oder man macht es explizit:

Code: Alles auswählen

# -*- coding: utf-8 -*-
class cpp(object):
    def __init__(self, cls):
        self.cls = cls

    def __call__(self, function):
        setattr(self.cls, function.__name__, function)

class Spam(object):
    pass


@cpp(Spam)
def eggs(self, x):
    print x

#oder
spam = cpp(Spam)

@spam
def foo(self, x):
    print x**2

Spam().eggs(1)
Spam().foo(2)
Das Leben ist wie ein Tennisball.
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

@sma: Du kannst FunctionType aus dem types Modul importieren anstatt den Typ mittels type() zu holen.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

str1442 hat geschrieben:@sma: Du kannst FunctionType aus dem types Modul importieren anstatt den Typ mittels type() zu holen.
Fand ich aufwendiger. So einen Import vermeide ich gerne. Auch stört mich aus ästhetischen Gründen, dass es nicht "types.function" sondern "types.FunctionType" heißt. Klar, man könnte ein "from types import FunctionType as function" machen, doch da hole ich mir, einfach weil es geht, den Typ lieber selbst. Geschmacksfrage.

Stefan
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Nicht schlecht diese "C++-Klassenwrapper" - ob nun explizit oder implizit. :lol:

Ich überlege gerade das für deprecated Methoden zu verwenden - mit einem entsprechenden decorator versehen. ;-)
Antworten