Python Child kann kein Modul des importierten Parents verwenden

7

Ich habe einen seltsamen Importfehler, wenn ich Inheritance in Python verwende.

In einer Elternklasse importiere ich das Modul sqlite3, in einer Kindklasse versuche ich dann eine sqlite3-Funktion zu verwenden, aber ich bekomme eine Fehlermeldung, dass "NameError: globaler Name 'sqlite3' nicht definiert ist". Warum passiert das? Wie repariere ich es?

Die 2 Klassen sind in separaten Dateien:

Parent.py

%Vor%

Child.py

%Vor%     
Jake M 22.01.2012, 00:04
quelle

3 Antworten

13

Das sqlite3-Modul wird in das übergeordnete Modul importiert, daher müssen Sie über dieses Modul darauf zugreifen

%Vor%

Es wird nicht direkt in das Child-Modul importiert, es sei denn, Sie sagen Python dies zu, zum Beispiel

%Vor%

Gibt Ihnen Zugriff auf alle Mitglieder des übergeordneten Moduls innerhalb des untergeordneten Moduls

    
babak 22.01.2012, 00:10
quelle
6

Das Kind hat einen eigenen Namensraum und Sie haben sqlite3 nicht importiert. Sie müssen also sqlite3 in Child.py importieren. Sie könnten auch import Parent.sqlite3 und dann Parent.sqlite3.connect aufrufen. Es hat keinen wirklichen Vorteil, dies zu tun, anstatt nur sqlite3 zu importieren, da Module nur einmal importiert werden (beim ersten Import erreicht der Code) und die folgenden Importe fügen das Modul nur dem aktuellen Namespace hinzu.

    
Glenn 22.01.2012 00:10
quelle
2

Sie haben das sqlite3 -Modul nicht in die Parent -Klasse importiert (Sie könnten es, aber das wäre wirklich seltsam). Sie haben sqlite3 in das Modul Parent.py importiert, das die Klasse Parent enthält, und das Modul sqlite3 in seiner Definition verwendet.

Dann importiert ein separates Modul das Modul Parent.py und definiert eine Unterklasse von Parent . Dies bringt nicht automatisch alles in der Klasse Parent in den Geltungsbereich [1] und es bringt sicherlich nicht alles mit, was in Geltung war, als Sie die Parent -Klasse in Parent.py in den Gültigkeitsbereich definierten. Wenn Sie andere Klassen in Parent.py deklariert haben, würden Sie nicht erwarten, dass diese Namen in Child enthalten sind, nur weil sie sich im selben Modul wie die Elternklasse befinden. Warum also erwarten Sie das eines Moduls, das gerade passiert um einige von Parent Methoden zu definieren?

Sie haben bereits einen Verweis auf den Namespace, in den sqlite3 importiert wurde. Sie haben die Klasse Parent daraus herausgelöst, um sie zu unterklassieren, wenn Sie class Child(Parent.Parent) angegeben haben. Also könntest du % Parent.sqlite3 verwenden, um auf sqlite3 zuzugreifen, aber das ist eine sehr seltsame Art, Module in Python zu verwenden.

Normalerweise ist es besser, einfach import sqlite3 am Anfang von Child.py hinzuzufügen. Dann wird jeder, der den Code liest, sehen, dass er sqlite3 verwendet. Wenn du sqlite3 siehst, die du aus Parent.py importiert hast, werden sie sich wundern, warum du nicht den normalen Weg benutzt hast, und denkst, dass du etwas kompliziertes machst, wie das sqlite3 Modul mit etwas Extra zu umhüllen Code, den Sie hinzugefügt haben. Und wenn Sie gerade import * from Parent gemacht haben, dann ist es nicht einmal offensichtlich, wo der sqlite3 Name herkommt, und Ihre Leser werden wirklich verwirrt sein. Und Ihr Code wird auf mysteriöse Weise nicht mehr funktionieren, wenn Sie entscheiden, dass Sie sqlite3 in Parent.py nicht importieren müssen, aber die Fehlermeldung wird Ihnen nichts über Parent.py sagen.

Wenn Sie einfache Dinge wie das Importieren eines Standardmoduls tun, sollten Sie dies auf einfache und offensichtliche Weise tun. Die Leute sind es gewohnt, das zu lesen, und werden es wirklich leicht aufnehmen, ohne dass sie aufhören müssen, darüber nachzudenken. Der "verwirrte Leser", der am ehesten ein Problem darstellt, ist selbst in ein paar Monaten, wenn Sie genau vergessen haben, wie dieser Code funktioniert hat; Sie möchten es so einfach wie möglich für sich selbst machen, wenn Sie die Aufgabe haben, es wieder herauszufinden.

[1] Das Vererben von einer Elternklasse hat überhaupt nichts mit scope zu tun, d. h. auf welche Namen Sie zugreifen können, ohne sie zu qualifizieren. Sie erhalten innerhalb des Klassenblocks, der die Kindklasse definiert, keinen Zugriff auf die Methoden und Klassenvariablen der Elternklasse . Es bedeutet, dass nach der Erstellung der Kindklasse das Namensauflösungsprotokoll für die Instanz- und Klassenvariablen im Elternobjekt angezeigt wird, wenn sie keine Objekte in der Kindklasse finden. Dies ist ein etwas subtiler Punkt, der im Grunde auf (1) innerhalb des Kindklassenblocks (einschließlich der Definitionen von Methoden) hinausläuft.% Co_de% gibt Ihnen einen Fehler, aber (2) nachdem die Kindklasse existiert (einschließlich wenn Methoden sind) tatsächlich ausgeführt) some_parent_method() (oder Child.some_parent_method() innerhalb einer Methode) findet die Methode des Elternteils.

    
Ben 22.01.2012 01:46
quelle