non hai importato il sqlite3
modulo nella classe Parent
(si potrebbe, ma sarebbe davvero strano). Hai importato sqlite3
nel modulo Parent.py
, che include la classe Parent
e utilizza il modulo sqlite3
nella sua definizione.
Quindi un modulo separato importa il modulo Parent.py
e definisce una sottoclasse di Parent
. Ciò non porta automaticamente tutto nella classe Parent
nell'ambito [1], e certamente non porta tutto ciò che era in ambito quando stavi definendo la classe Parent
in Parent.py
nell'ambito. Se hai dichiarato altre classi in Parent.py
, non ti saresti aspettato che quei nomi fossero nello scope in Child
solo perché erano nello stesso modulo della sua classe genitore, quindi perché dovresti aspettarti questo di un modulo che viene usato solo in definendo alcuni dei metodi di Parent
?
Hai già un riferimento allo spazio dei nomi in cui è stato importato sqlite3
; hai preso la classe Parent
per creare una sottoclasse quando hai detto class Child(Parent.Parent)
. Quindi tu potresti usare Parent.sqlite3
per accedere a sqlite3
, ma questo è un modo molto strano di usare i moduli in Python.
Normalmente è meglio aggiungere import sqlite3
all'inizio di Child.py
. Quindi chiunque legga il codice vedrà che usa sqlite3
.Se vedi che stai usando, ti chiederai perché non hai usato il modo normale e pensi che potresti fare qualcosa di complicato come avvolgere il modulo sqlite3
con un altro codice aggiunto. E se hai appena fatto import * from Parent
, allora non è nemmeno ovvio lo da cui proviene il il nome sqlite3
ei tuoi lettori saranno davvero confusi. E il tuo codice smetterà misteriosamente di funzionare quando decidi di non aver bisogno di importarein Parent.py
dopotutto, ma il messaggio di errore non ti dirà nulla su Parent.py
.
In genere, se stai facendo cose ovvie come l'importazione di un modulo standard, dovresti farlo in modo semplice e ovvio. Le persone sono abituate a leggerlo e lo prenderanno molto facilmente senza bisogno di fermarsi a pensarci. Il "lettore confuso" che è più probabile che sia un problema è te stesso in pochi mesi in cui hai dimenticato esattamente come funzionava questo codice; vuoi renderlo il più semplice possibile per te stesso quando hai il compito di capirlo di nuovo.
[1] Ereditare da una classe genitore non ha nulla a che fare con portata, vale a dire ciò che i nomi si può accedere senza di loro qualificazione. Non si accede ai metodi e alle variabili di classe della classe genitore all'interno del blocco di classe che definisce la classe figlio. Ciò che significa è che dopo che la classe figlia è stata creata, il protocollo di risoluzione dei nomi per le variabili di istanza e classe si troveranno in Parent se non trovano le cose nella classe child. Questo è un punto un po 'sottile, che fondamentalmente si riduce a (1) all'interno del blocco classe figlio (comprese le definizioni dei metodi) some_parent_method()
ti darà un errore, ma (2) dopo che la classe figlio esiste (incluso quando i metodi sono effettivamente eseguiti) Child.some_parent_method()
(o self.some_parent_method()
all'interno di un metodo) troverà il metodo del genitore.
Oppure utilizzare semplicemente un 'import sqlite3' sul modulo figlio. – jsbueno
Perché mai accedere a sqlite3 tramite Parent? Inoltre, "import *" non è eccezionale. –
D'accordo, questa è una cattiva risposta ad accettare - "import sqlite3'' è il modo corretto per farlo. –