Cosa c'è di sbagliato nelle importazioni relative in Python?

88

Recentemente ho aggiornato le versioni di pylint , un popolare strumento di controllo dello stile di Python.

È diventato balistico in tutto il mio codice, sottolineando i luoghi in cui importare i moduli nello stesso pacchetto, senza specificare il percorso completo del pacchetto.

Il nuovo messaggio di errore è W0403.

W0403: Relative import %r, should be %r

Used when an import relative to the package directory is detected.

Esempio

Ad esempio, se i miei pacchetti sono strutturati in questo modo:

/cake
  /__init__.py
  /icing.py
  /sponge.py
/drink

e nel pacchetto spugnoso scrivo:

import icing

invece di

import cake.icing

Riceverò questo errore.

Pur comprendendo che non tutti i messaggi di Pylint hanno la stessa importanza, e non ho paura di eliminarli, non capisco perché una tale pratica sia considerata una cattiva idea.

Speravo che qualcuno potesse spiegare le insidie, quindi avrei potuto migliorare il mio stile di codifica piuttosto che (come ho intenzione di fare attualmente) di disattivare questo avviso apparentemente spurio.

    
posta Oddthinking 04.08.2012 - 17:29
fonte

2 risposte

93

Il problema di import icing è che non sai se è un'importazione assoluta o un'importazione relativa. icing potrebbe un modulo nel percorso di Python, o un pacchetto nel modulo corrente. Questo è abbastanza fastidioso quando un pacchetto locale ha lo stesso nome di un pacchetto di libreria standard python.

Puoi fare from __future__ import absolute_import che disattiva del tutto le importazioni relative implicite. Viene descritto, anche con questa giustificazione sull'ambiguità, in PEP 328 . Credo che Python 3000 abbia le importazioni relative implicite completamente disattivate.

Puoi ancora fare importazioni relative, ma devi farlo esplicitamente, in questo modo:

from . import icing
    
risposta data 04.08.2012 - 17:36
fonte
47

Ci sono alcuni buoni motivi:

  1. Le importazioni relative si interrompono facilmente quando sposti un modulo.

    Immagina di avere un modulo foo.bar , un foo.baz e un baz nel tuo pacchetto. foo.bar importa foo.baz , ma usando un'importazione relativa.

    Ora, se dovessi spostare foo.bar in bar , all'improvviso il tuo modulo sta importando una percentuale diversa dibaz!

  2. Le importazioni relative sono ambigue. Anche senza spostare il modulo bar nell'esempio precedente, un nuovo sviluppatore in arrivo al tuo progetto potrebbe essere perdonato per non rendersi conto che baz è in realtà foo.baz invece del pacchetto baz di root.

    Le importazioni assolute rendono esplicito quale modulo viene utilizzato. E come predica% co_de, l'esplicito è meglio di implicito.

  3. Python 3 ha disabilitato del tutto le importazioni relative implicite; le importazioni sono ora sempre interpretate come assolute, nel senso che nell'esempio precedente import this importa sempre il modulo di primo livello. Dovrai invece utilizzare la sintassi di importazione esplicita ( import baz ).

    Portare l'esempio da Python 2 a 3 porterebbe quindi a problemi imprevisti, utilizzando le importazioni assolute ora renderà il tuo codice a prova di futuro.

risposta data 04.08.2012 - 17:43
fonte

Leggi altre domande sui tag