Seite 1 von 1

Klassen-Methoden auslagern

Verfasst: Samstag 8. August 2009, 14:55
von Roque
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

Verfasst: Samstag 8. August 2009, 15:05
von 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.

Verfasst: Samstag 8. August 2009, 15:06
von EyDu
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

Verfasst: Montag 10. August 2009, 08:38
von Roque
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

Verfasst: Montag 10. August 2009, 08:53
von CM
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

Verfasst: Montag 10. August 2009, 09:07
von sma
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

Verfasst: Montag 10. August 2009, 12:15
von EyDu
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)

Verfasst: Montag 10. August 2009, 13:40
von str1442
@sma: Du kannst FunctionType aus dem types Modul importieren anstatt den Typ mittels type() zu holen.

Verfasst: Dienstag 11. August 2009, 08:44
von sma
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

Verfasst: Dienstag 11. August 2009, 09:17
von CM
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. ;-)