Con l'aiuto della posta di Guido fornita da @kindall, possiamo comprendere il processo di importazione standard come il tentativo di trovare il modulo in ogni membro di sys.pathe il file come risultato di questa ricerca (maggiori dettagli in Moduli e importazioni PyMOTW .). Quindi se il modulo si trova in un percorso assoluto sys.pathil risultato è assoluto, ma se si trova in un percorso relativo sys.pathil risultato è relativo.
Ora il site.pyfile di avvio si occupa di fornire solo il percorso assoluto sys.path, eccetto quello iniziale '', quindi se non lo cambi con altri mezzi che impostando il PYTHONPATH (il cui percorso è anche reso assoluto, prima del prefisso sys.path), otterrai sempre un assoluto path, ma quando si accede al modulo tramite la directory corrente.
Ora, se ingannate sys.path in un modo divertente, potete ottenere qualsiasi cosa.
Come esempio, se si dispone di un modulo di esempio foo.pyin /tmp/con il codice:
import sys
print(sys.path)
print (__file__)
Se vai in / tmp ottieni:
>>> import foo
['', '/tmp', '/usr/lib/python3.3', ...]
./foo.py
Quando /home/usersei dentro , se aggiungi /tmpil PYTHONPATHtuo ottieni:
>>> import foo
['', '/tmp', '/usr/lib/python3.3', ...]
/tmp/foo.py
Anche se aggiungi ../../tmp, verrà normalizzato e il risultato è lo stesso.
Ma se invece di PYTHONPATHusare direttamente un percorso divertente ottieni un risultato divertente quanto la causa.
>>> import sys
>>> sys.path.append('../../tmp')
>>> import foo
['', '/usr/lib/python3.3', .... , '../../tmp']
../../tmp/foo.py
Guido spiega nel thread sopra citato, perché python non tenta di trasformare tutte le voci in percorsi assoluti:
non vogliamo dover chiamare getpwd () su ogni importazione .... getpwd () è relativamente lento e talvolta può fallire completamente,
Quindi il tuo percorso viene utilizzato così com'è .