OO-Prinzipien und Python

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.
Marky
User
Beiträge: 24
Registriert: Donnerstag 22. Januar 2009, 08:12

Hallo zusammen,

ich finde übrigens, man sollte zu dem Thema OO-Design und Python ein eigenes Forum aufmachen :wink:
Aber jetzt meine Frage mit der Hoffnung auf Meinungen dazu.
Ich befinde mich in einem Modul A in dem ein Objekt einer Klasse erzeugt wird. Bei der Instanziierung wird als Konstruktor-Parameter eine Methode aus einem anderen Modul B übergeben, die per

Code: Alles auswählen

from B import method
bekannt gemacht wird.
Ich hoffe das ist durch meine Erklärung erstmal soweit verstanden.
Ich hab' ja mittlerweile eingesehen, dass man pythonisch denken soll :roll:
Ich glaube, man wollte wohl Code-Duplizierung verhindern oder gemeinsamen Code auslagern. Ich frage mich jetzt nur, ob das pythonisch ist oder eher schlechtes Code-Design?
Ich denke, sowas könnte man ja auch mit Hilfe einer Delegation an die entsprechende Klasse lösen. Mich kommt sowas vor, wie "durch die Brust ins Auge". Lasse mich aber gerne von dem Nutzen und den Vorteilen solcher Konstrukte überzeugen und vor dem Hintergrund guten und wartbaren Code zu erzeugen.
Ich meine ... machbar ist das, aber ist es auch sinnvoll? Das sollte jetzt übrigens keine rhetorische Frage sein...
Was meinen denn die Python-Freunde dazu ...?
Gruß
Marky
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

IMHO ist es durchaus gut, dem Konstruktor irgedwelche Methoden als Parameter zu geben, wenn sie noetig sind.

Aber mit so wenig Code kann man schwer sagen, ob man dein Problem nun besser loesen kann oder nicht.
Marky
User
Beiträge: 24
Registriert: Donnerstag 22. Januar 2009, 08:12

Kannst Du mir Beispiele nennen, wo es Sinn macht/machen könnte ?
Gruß
Marky
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Marky hat geschrieben:Kannst Du mir Beispiele nennen, wo es Sinn macht/machen könnte ?
Man könnte z.B. irgendwelchen Views auf Daten dadurch einen Sortier- oder Filter-Algorithmus mitgeben - je nachdem, was gerade nötig ist.

Die sort-Methode bei Listen akzeptiert eine Funktion, die dann entscheidet, wie genau sortiert wird. Oder auch die sub-Methode bei Regulären Ausdrücken nimmt eine Funktion, die dann je nach Treffer andere Strings zum ersetzen liefert. Gibt viele Möglichkeiten.
Marky
User
Beiträge: 24
Registriert: Donnerstag 22. Januar 2009, 08:12

ok, leuchtet mir so langsam ein. Was die sort-Funktionalität angeht, gibt es sowas ähnliches in Java ja auch, indem man bestimmten Klassen eine Comparator-Instanz übergeben kann.
Hier sind dann zusätzlich auch Methoden möglich... ok ...
Gruß
Marky
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

In Java werden Klasseninstanzen uebergeben, weil es keine First Class Functions gibt und Klassen keine Objekte sind, die man herumreichen koennte.
BlackJack

Ich verstehe den Ausgangsbeitrag nicht so ganz. Aus dem Modul `B` wird keine Methode, sondern eine Funktion importiert, oder allgemein gesprochen wohl ein "callable".

Sinnvolle Beispiele: Überall wo man unter bestimmten Umständen einen Rückruf von dem Objekt haben möchte, dass man da erstellt, oder wo das Objekt später diese Funktion aufrufen möchte um zum Beispiel andere Objekte zu erstellen.
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

BlackJack hat geschrieben:Ich verstehe den Ausgangsbeitrag nicht so ganz. Aus dem Modul `B` wird keine Methode, sondern eine Funktion importiert, oder allgemein gesprochen wohl ein "callable".
Woher weißt du, dass method callable ist? Vom Namen her?
Woher weißt du, dass method keine Methode ist?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

bords0 hat geschrieben:Woher weißt du, dass method callable ist? Vom Namen her?
Von deiner Beschreibung.
bords0 hat geschrieben:Woher weißt du, dass method keine Methode ist?
Weil man keine Methoden importieren kann sondern nur Module, Klassen und Funktionen.
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Leonidas hat geschrieben:
bords0 hat geschrieben:Woher weißt du, dass method callable ist? Vom Namen her?
Von deiner Beschreibung.
Ich hab doch noch gar nix geschrieben... und der OP hatte explizit Methode geschrieben, wenn du das nicht anerkennst, wie kommst du dann auf callable?
Leonidas hat geschrieben:
bords0 hat geschrieben:Woher weißt du, dass method keine Methode ist?
Weil man keine Methoden importieren kann sondern nur Module, Klassen und Funktionen.
Steht so ein Unsinn irgendwo in der Doku? Das sollte man melden. Es ist überhaupt kein Problem, Methoden zu importieren:

Code: Alles auswählen

>>> class A(object):
	def bla(self):
		pass

	
>>> method1 = A.bla
>>> method2 = A().bla
>>> from __main__ import method1 as m1, method2 as m2
>>> m1
<unbound method A.bla>
>>> m2
<bound method A.bla of <__main__.A object at 0x023991B0>>
>>> 
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Leonidas hat geschrieben:
bords0 hat geschrieben:Woher weißt du, dass method keine Methode ist?
Weil man keine Methoden importieren kann sondern nur Module, Klassen und Funktionen.
Steht so ein Unsinn irgendwo in der Doku? Das sollte man melden. Es ist überhaupt kein Problem, Methoden zu importieren: [...]
Ich glaube, er wollte darauf raus, dass es nicht in der Form

Code: Alles auswählen

from module.classname import mehtod
geht, oder allgemeiner, dass man mit import nur an objekte kommt, die auf Modulebene einen Namen haben.
Marky
User
Beiträge: 24
Registriert: Donnerstag 22. Januar 2009, 08:12

immer locker bleiben :wink: stimmt ja schon, dass man sich präzise ausdrücken sollte. Da ich von Java komme ist für mich alles eine Methode.
In Python wird da ja unterschieden.
Im konkreten Fall also, handelt es sich um eine Funktion.
Gruß
Marky
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Marky hat geschrieben:Da ich von Java komme ist für mich alles eine Methode.
In Python wird da ja unterschieden.
Eigentlich unterscheide ich da nicht. Es sind beides Funktionen und manchmal sind sie an Klassen gebunden, es sind aber dennoch Funktionen die die Instanz der Klasse als Parameter mitbekommen. Mehr nicht.
Marky
User
Beiträge: 24
Registriert: Donnerstag 22. Januar 2009, 08:12

na ja ... du vielleicht nicht, andere schon:

http://openbook.galileocomputing.de/pyt ... 12_001.htm

Wenn man aus objektorientierter Sicht das Ganze betrachtet, hat eine Klasse für mich Methoden und keine Funktionen.
Funktionen bringe ich mit prozeduraler Programmierung in Verbindung.
Aber sei's drum...
Gruß
Marky
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Marky hat geschrieben:na ja ... du vielleicht nicht, andere schon:
Das Buch ist halt von Java-Programmierern geschrieben worden, die von Python nicht so die Ahnung haben. Siehe Kritik zu dem Buch im Forum.

Funktionen bringe ich persönlich eher mit Funktionaler Programmierung in Verbindung. Das mache ich in Python aber auch recht gerne.

Aus Objektorientierter Sicht gesehen hast du in einem Objekt in Python nur Attribute. Diese sind eben Callable (das was du als Methoden bezeichnest, Funktionen, es könnten aber theoretisch auch Klassen sein) oder nicht (also Properties und generell Objekte die kein ``__call__`` implementieren).

Argh, meine Erklärung ist irgendwie unklar.. mal sehen, vielleicht erklärt es jemand besser.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Leonidas hat geschrieben:Argh, meine Erklärung ist irgendwie unklar.. mal sehen, vielleicht erklärt es jemand besser.
Ich probiere es mal. :)

Code: Alles auswählen

foo.bar()
Ist die abkürzende Schreibweise von:

Code: Alles auswählen

getattr(foo, "bar")()
Dabei ist egal ob bar jetzt eine Funktion/Methode, ein beliebiges Objekt oder Klasse ist, Hauptsache bar ist "callable".

Und ob man jetzt

Code: Alles auswählen

class Foo:
    class bar: pass
foo = Foo()
print foo.bar()
noch als astreinen Methodenaufruf bezeichnen kann...
Marky
User
Beiträge: 24
Registriert: Donnerstag 22. Januar 2009, 08:12

... ist fraglich.
Verstehe.
Gruß
Marky
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Zudem man noch Funktionen an Klassen binden kann, die vorher nicht Teil der Klasse waren.

Code: Alles auswählen

class A(object):
    pass

def foo(self):
    print "Methode der Instanz", self

A.foo = foo
a = A()
a.foo()
foo(a)
Da jetzt speziell zwischen Methode und Funktion zu unterscheiden scheint mir etwas künstlich. Natürlich, durch das binden an eine Klasse passiert etwas Magie, aber das ist mir zu verschwommen um da exakt unterscheiden zu wollen.
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Leonidas hat geschrieben:Da jetzt speziell zwischen Methode und Funktion zu unterscheiden scheint mir etwas künstlich.
Warum machst du dann beim Importieren diesen Unterschied, d.h. behauptest, dass Funktionen importiert werden können, Methoden aber nicht? :?
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Man kann nur Dinge direkt aus dem Modul Namespace importieren. Da Methoden nunmal im Namespace einer Klasse definiert sind, kann man sie nicht importieren. Das trifft auch auf jedes andere Objekt zu, das nicht direkt im Modul Namespace liegt.

Du musst einfach Python's Klassenkonzept verstehen:

Die Methoden einer Python Klasse sind eigentlich Funktionen. Du gibst das "self" bei einer Methode nicht umsonst ein! Ein Aufruf der Form:

Code: Alles auswählen

a.b(args)
einer Instanz a wird konvertiert in das hier:

Code: Alles auswählen

a.__class__.b(a, args)
Deswegen gibt man das self an. Es gibt keinen Unterschied zwischen einer Methode und einer Funktion, außer dem, das eine an eine solche Methode immer die eigene Instanz als erstes Argument überliefert bekommt. Du könntest die Methode auch direkt über a.__class__.b aufrufen, und ihr irgendetwas anderes mitgeben, das als self behandelt werden soll.

Weiters, eine Funktion ist "nur" ein callable. Callable ist jedes Objekt, das eine __call__ Methode besitzt. Mach doch mal dir() auf eine Funktion. Du kannst jedes Spezialverhalten in Python durch __doubleunderscore__ Methoden emulieren, es gibt keine "bevorzugten" Objekte. Selbst Klassen sind Objekte, und bei der Instanziierung einer Klasse wird deren eigene __call__ Methode aufgerufen. (Deswegen hat bei solchen Metaklassen genannten Klassen das überschreiben von __call__ lustige Effekte).
Antworten