2012-07-30 1 views
17

Immaginate la struttura di directory:Le importazioni non dovrebbero essere assolute per impostazione predefinita in python27?

 
/
    a/ 
     __init__.py 
     b.py 
     c.py 
    c.py 

File /a/b.py assomiglia:

 
import c 
should_be_absolute = c 

Tutti gli altri file (tra cui __init__) sono vuoti.

Quando si esegue uno script di test (usando python 2.7):

import a.b 
print a.b.should_be_absolute 

con PYTHONPATH=/ da una directory vuota (quindi nulla viene aggiunto PYTHONPATH dalla directory corrente) ottengo

<module 'a.c' from '/a/c.py'> 

dove secondo a PEP 328 e la dichiarazione import <> is always absolute Mi aspetto:

<module 'c' from '/c.py'> 

L'output è come previsto quando rimuovo il file /a/c.py.

Cosa mi manca? E se questo è il comportamento corretto - come importare il modulo c da b (anziché a.c)?

Aggiornamento:

Secondo python dev mailing list sembra essere un bug nella documentazione. Le importazioni sono non per default in python27.

+0

Qual è il tuo pythonpath completo? È solo /? Probabilmente dovresti usare il nome del pacchetto radice – jdi

+3

FWIW, questo funziona come previsto in Python 3. – geoffspear

+0

@jdi - sì la radice è l'unica cosa nel PYTHONPATH (modificato il post originale per renderlo più esplicito) – karolx

risposta

26

è necessario aggiungere from __future__ import absolute_import o utilizzare importlib.import_module('c') su Python 2.7

E 'default su Python 3.

C'è stato un problema in Python: __future__.py and its documentation claim absolute imports became mandatory in 2.7, but they didn't.

+2

Hai ragione! Dopo ulteriori scavi ho trovato il link alla mailing list [python-dev] (http://python.6.n6.nabble.com/status-of-absolute-import-w-python-2-7-td1850742.html) confermando che la funzione absolute_import non è attiva per impostazione predefinita in python27. – karolx

+0

tipo di ridicolo ... –

0

Se si aggiunge solo / a PYTHONPATH, l'ordine di ricerca potrebbe comunque cercare c nella directory corrente. Sarebbe molto meglio se è stato inserito tutto sotto un package principale, e che sia sollevato assolutamente:

/myPackage 
    a/ 
     __init__.py 
     b.py 
     c.py 
    __init__.py 
    c.py 

E un PYTHONPATH come: export PYTHONPATH=/:$PYTHONPATH

Quindi nel tuo a.c si farebbe e di questi:

from myPackage import c 
from myPackage.c import Foo 
import myPackage.c 

In questo modo, è sempre relativo al pacchetto.

+0

Grazie ma il la domanda è più è questo un comportamento corretto piuttosto che come riorganizzare il codice per farlo funzionare. Il vero problema che sto risolvendo è che la 'c' è il nome del modulo build-in python e il codice nel pacchetto che sto lavorando lo sta oscurando (e secondo i documenti Python non dovrebbe) – karolx

-1

"Assoluto" non significa quello che si pensa di fare; invece, significa che la "solita" procedura di risoluzione del pacchetto ha luogo: prima, cerca nella directory del pacchetto, quindi in tutti gli elementi di sys.path; che include gli elementi di PYTHONPATH.

Se si utilizza lo strumento , è possibile utilizzare strumenti come il modulo imp, ma si consiglia di non utilizzarlo per qualcosa di simile. Perché in generale, non dovresti mai creare un modulo con lo stesso nome di uno nella distribuzione standard di Python.

+0

Grazie @Ivo ma il [PEP 328 # rationale-per-absolute-import] (http://www.python.org/dev/peps/pep-0328/#rationale-for-absolute-imports) afferma che l'importazione assoluta sarà sempre un modulo o un pacchetto raggiungibile da sys.path_. Non c'è prima nulla nella ricerca nella directory del pacchetto. Puoi indicare alcune risorse che documentano il comportamento che hai descritto per favore? – karolx

+0

http://docs.python.org/reference/simple_stmts.html#import è molto chiaro sul processo mentre viene implementato: "Se il modulo che si sta importando deve essere contenuto in un pacchetto, il secondo argomento viene passato a find_module(), __path__ sul pacchetto padre, viene utilizzato come origine dei percorsi. " – Ivo

+0

"prima appare nella directory del pacchetto". No, è un'importazione relativa. –