import Problem, class not defined

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
helmut25
User
Beiträge: 15
Registriert: Sonntag 31. Januar 2016, 19:50

Hallo,
ich habe folgendes Problem:
1. script1.py enthält "class A"
2. script2.py enthält eine Unterklasse B(A)und importiert script1
3. in script3.py importiere ich script2, instanziere B und erhalte den Fehler
"class B(A):"
"NameError: name 'A' is not defined"

Was läuft hier falsch?

Gruss, Helmut
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

import ist kein include wie in C. Du musst in script2 schon auf script1.A zugreifen oder A aus script1 importieren mit from import.
helmut25
User
Beiträge: 15
Registriert: Sonntag 31. Januar 2016, 19:50

DasIch hat geschrieben:import ist kein include wie in C. Du musst in script2 schon auf script1.A zugreifen oder A aus script1 importieren mit from import.
Was meinst Du genau mit "in script2 schon auf script1.A zugreifen"?
Ich importiere doch in script2 das script1 und leite die Klasse B von A ab.

"oder A aus script1 importieren mit from import"
in script3? Wie sieht die genaue Syntax aus?
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

script3 ist vollkommen irrelevant.

Das Problem ist eben dass du in script2 nicht B von A ableitest weil A in script2 nicht definiert ist. Ein import wirft dir nicht einfach irgendwelche Namen in den Namensraum sondern nur das Modul über dass du auf die in dem Modul definierten Objekte zugreifst. Wenn du also auf A in script2 zugreifen möchtest oder davon ableiten möchtest musst du explizit script1.A schreiben oder in script2 A importieren mit from script1 import A.
helmut25
User
Beiträge: 15
Registriert: Sonntag 31. Januar 2016, 19:50

DasIch hat geschrieben:script3 ist vollkommen irrelevant.

Das Problem ist eben dass du in script2 nicht B von A ableitest weil A in script2 nicht definiert ist. Ein import wirft dir nicht einfach irgendwelche Namen in den Namensraum sondern nur das Modul über dass du auf die in dem Modul definierten Objekte zugreifst. Wenn du also auf A in script2 zugreifen möchtest oder davon ableiten möchtest musst du explizit script1.A schreiben oder in script2 A importieren mit from script1 import A.
OK, bin jetzt schon mal einen Schritt weiter.
Wenn ich nach dem Instanzieren in script3 eine Methode der abgeleiteten Klasse (ohne Parameter)
aufrufen will, kommt die Meldung:
"TypeError: unbound method mymethod() must be called with B instance as first argument (got type instance instead)"

Was soll das denn jetzt?
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

@helmut25: was Du da genau machst, weiß hier niemand. Zeig doch mal Deinen Code.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Willkommen im Forum und zu Python!

Mach einen Schritt zurueck und arbeite ein Tutorial durch, z.B. das aus der Python Dokumentation.
Es macht keinen Sinn, wenn du dein Programm zusammenraetst.
helmut25
User
Beiträge: 15
Registriert: Sonntag 31. Januar 2016, 19:50

Sirius3 hat geschrieben:@helmut25: was Du da genau machst, weiß hier niemand. Zeig doch mal Deinen Code.
from script2 import B

bObj=B
d=bObj.mymethod()
print d
helmut25
User
Beiträge: 15
Registriert: Sonntag 31. Januar 2016, 19:50

cofi hat geschrieben:Willkommen im Forum und zu Python!

Mach einen Schritt zurueck und arbeite ein Tutorial durch, z.B. das aus der Python Dokumentation.
Es macht keinen Sinn, wenn du dein Programm zusammenraetst.
Sorry, aber wenn man von PHP kommt (wo OOP ziemlich easy ist),
dann ist die Python-Mimik schon sehr gewöhnungbedürftig :?
BlackJack

@helmut25: Deine Probleme in diesem Thema haben nichts mit OOP zu tun sondern mit Namensräumen. Wahrscheinlich ist das auch das Problem wenn Du von PHP aus an die Sache gehst, den Namensräume sind in PHP ein relativ neues Feature, vielleicht hast Du damit also vorher noch nicht gearbeitet.

OOP ist in PHP nicht ”easy” sondern ziemlich nervig weil man merkt, dass das nachträglich drauf getackert wurde. Das man unter bestimmten Umständen Rückgabewerte von Methoden zwingend an Namen binden musste um damit weiterarbeiten zu können empfand ich als *sehr* nervig, als ich mich das letzte mal damit auseinandersetzen musste.

Ansonsten ist OOP in Python nicht schwerer als in PHP. Vielleicht an der einen oder anderen Stelle anders, aber nicht schwerer. Und in beiden Sprachen nicht leicht, aber das liegt eher in der Natur von OOP und nicht an den Sprachen.

Vergiss am besten PHP und denk nicht, dass Du weil Du schon eine Programmiersprache kannst, darum herum kommst die Grundlagen einer anderen Sprache durch zu arbeiten. Mit der Vorstellung wie Dinge zu funktionieren haben, nämlich so wie man sie aus Sprache X kennt, zu versuchen in einer anderen Sprache Y zu programmieren, führt in der Regel zu grausigem Code und Fehlern und einer Menge Frust. Das gilt für alle Sprachen X und Y sofern sie sich nicht *sehr* ähnlich sind. Und Python und PHP sind nicht ähnlich.

Edit: Es würde vielleicht ein wenig helfen wenn Du Module nicht als `script` bezeichnen würdest. So eine Datei ist ein Modul und ein Modul ist ein Namensraum. Und wie schon gesagt wurde ist Python's ``import`` kein ``import`` oder ``require`` was einfach den Inhalt einer Textdatei in eine andere Einfügt und so alles in den gleichen Namensraum wirft.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

helmut25 hat geschrieben:from script2 import B

bObj=B
Damit erstellst du nur einen zusätzlichen Namen für das Objekt.

Wenn du eine Instanz der Klasse haben möchtest geht das so:
[Codebox=python file=Unbenannt.py]bObj = B()[/Codebox]
Natürlich würde man sinnvollere Bezeichnernamen wählen. "Obj" hat beispielsweise nichts in Namen zu suchen, vor allem, da in Python alles ein Objekt ist, egal ob es sich um Zahlen, Klassen oder Funktionen handelt.
helmut25
User
Beiträge: 15
Registriert: Sonntag 31. Januar 2016, 19:50

BlackJack hat geschrieben:@helmut25: Deine Probleme in diesem Thema haben nichts mit OOP zu tun sondern mit Namensräumen. Wahrscheinlich ist das auch das Problem wenn Du von PHP aus an die Sache gehst, den Namensräume sind in PHP ein relativ neues Feature, vielleicht hast Du damit also vorher noch nicht gearbeitet.

OOP ist in PHP nicht ”easy” sondern ziemlich nervig weil man merkt, dass das nachträglich drauf getackert wurde. Das man unter bestimmten Umständen Rückgabewerte von Methoden zwingend an Namen binden musste um damit weiterarbeiten zu können empfand ich als *sehr* nervig, als ich mich das letzte mal damit auseinandersetzen musste.

Ansonsten ist OOP in Python nicht schwerer als in PHP. Vielleicht an der einen oder anderen Stelle anders, aber nicht schwerer. Und in beiden Sprachen nicht leicht, aber das liegt eher in der Natur von OOP und nicht an den Sprachen.

Vergiss am besten PHP und denk nicht, dass Du weil Du schon eine Programmiersprache kannst, darum herum kommst die Grundlagen einer anderen Sprache durch zu arbeiten. Mit der Vorstellung wie Dinge zu funktionieren haben, nämlich so wie man sie aus Sprache X kennt, zu versuchen in einer anderen Sprache Y zu programmieren, führt in der Regel zu grausigem Code und Fehlern und einer Menge Frust. Das gilt für alle Sprachen X und Y sofern sie sich nicht *sehr* ähnlich sind. Und Python und PHP sind nicht ähnlich.

Edit: Es würde vielleicht ein wenig helfen wenn Du Module nicht als `script` bezeichnen würdest. So eine Datei ist ein Modul und ein Modul ist ein Namensraum. Und wie schon gesagt wurde ist Python's ``import`` kein ``import`` oder ``require`` was einfach den Inhalt einer Textdatei in eine andere Einfügt und so alles in den gleichen Namensraum wirft.
OK, hast im Prinzip recht, werde mich bemühen :)
Trotzdem habe ich jetzt ein Problemchen, das ich trotz intensiver Recherche nicht auf die Reihe kriegen konnte.
Nämlich dann, wenn ich eine Methode aufrufe, die in der Elternklasse der instanzierten Klasse definiert ist.
Nachdem ich so einiges durchgelesen habe, müsste man wohl eine Art Kopie der Methode in der Kindklasse anlegen
und einen super-Befehl absetzen:

def mymethod(self,param):
return super(<Elternklasse>,self).mymethod(param)

Doch auch das produziert den schon erwähnten Fehler:

TypeError: unbound method mymethod() must be called with <Kindklasse> instance as first argument (got str instance instead)
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

helmut25 hat geschrieben:
Sirius3 hat geschrieben:@helmut25: was Du da genau machst, weiß hier niemand. Zeig doch mal Deinen Code.
from script2 import B

bObj=B
d=bObj.mymethod()
print d
Da fehlen Klammern hinter der Klasse B, damit diese auch tatsächlich instanziiert wird. So wie du es jetzt machst, bindest du bloß die Klasse an sich, jedoch nicht die Instanz dieser Klasse an `bObj`. Das würde übrigens auch nicht in PHP ohne die Klammen funktionieren.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@helmut25
`super()` ist dazu gedacht, eine Methode der Elternklasse aufzurufen, wenn der Methodenname auch gleichzeitig in der abgeleiteten Klasse existiert. Mit anderen Worten: Wenn die Methode `foo()` in Klasse A definiert wurde und Klasse B eine abgeleitete Klasse von A darstellt und ebenfalls `foo()` definiert hat, dann ist `super()` eine Möglichkeit, um aus Klasse B heraus auf das `foo()` von Klasse A zuzugreifen.

Bei dir sieht es aber schlichtweg so aus, als wenn du die Klasse nach wie vor nicht instanziiert hast, sondern versehentlich mit der Klasse an sich arbeitest, wie ich ja in meinem vorherigen Beitrag beschrieben habe. Da wird dir `super()` nicht weiterhelfen.

Meiner Meinung nach solltest du dich zumindest mal mit den Grundlagen von OOP vertraut machen, wenn du schon kein komplettes Python-Tutorium durcharbeiten willst. Deine Beiträge lassen darauf schließen, dass noch einiges an Nachholbedarf bei dem Thema für dich besteht. Das wird dir am Ende mehr bringen als diese Ratespielchen.
Antworten