Importancia de Python: ¿paquetes o módulos?

No estaba claro cómo nombrar correctamente esta pregunta.

Caso 1

Supongamos que tengo la siguiente estructura de directorios.

foo | +- bar/__init__.py | +- bar.py 

Si tengo

 from foo import bar 

¿Cómo puedo saber qué barra ( bar.py o bar/__init__.py ) se está importando? ¿Hay alguna manera fácil de detectar automáticamente que esto ocurra?

Caso 2

 foo | +- foo.py | +- other.py 

Si other.py tiene la línea

 import foo 

¿Cómo puedo saber qué foo (foo o foo.foo) se está importando? De nuevo, ¿hay alguna manera fácil de detectar automáticamente que esto ocurre?

TLDR; un paquete tiene prioridad sobre un módulo del mismo nombre si están en el mismo directorio.

De los documentos:

“Cuando se importa un módulo llamado spam , el intérprete busca un archivo llamado spam.py en el directorio actual, y luego en la lista de directorios especificada por la variable de entorno PYTHONPATH . Esta tiene la misma syntax que la variable de shell PATH, que es, una lista de nombres de directorio “.

Esto es un poco engañoso porque el intérprete también buscará un paquete llamado spam (un directorio llamado spam contiene un archivo __init__.py ). Dado que las entradas del directorio están ordenadas antes de buscar, los paquetes tienen prioridad sobre los módulos con el mismo nombre si se encuentran en el mismo directorio porque el spam aparece antes del spam spam.py .

Tenga en cuenta que el “directorio actual” es relativo a la ruta principal del script (donde __name__ == '__main__' is True ). Así que si estás en /home/billg calling /foo/bar.py , “directorio actual” se refiere a /foo .

de una shell de python:

 from foo import bar print bar.__file__ 

debería decirle qué archivo ha sido importado

Robar

Los paquetes (directorios con __init__.py ) tienen prioridad sobre los módulos. La documentación de este hecho es difícil de encontrar, pero puedes ver esto en la fuente: python 2.7 , python 3.6 (gracias @qff por el hallazgo).

También necesitará un __init__.py dentro del directorio foo para que su ejemplo funcione.

Si other.py está dentro de foo/ entonces cargará foo.py (no el directorio foo/ ) porque buscará primero en el directorio actual (a menos que haya jugado con PYTHONPATH o sys.path).

en el primer caso, estás intentando importar la barra de funciones del archivo ‘foo.py’

En el segundo, estás intentando importar el archivo ‘foo.py’