python - proposal - pycodestyle
PEP8: importaciĆ³n no en la parte superior del archivo con sys.path (6)
¿Ya probaste lo siguiente:
import sys
from importlib import import_module
sys.path.insert("..", 0)
# import module
my_mod = import_module(''my_module'')
# get method or function from my_mod
my_method = getattr(my_mod , ''my_method'')
Problema
PEP8 tiene una regla sobre colocar las importaciones en la parte superior de un archivo:
Las importaciones siempre se colocan en la parte superior del archivo, justo después de los comentarios y cadenas de documentos de cualquier módulo, y antes de las constantes y variables globales del módulo.
Sin embargo, en ciertos casos, me gustaría hacer algo como:
import sys
sys.path.insert("..", 0)
import my_module
En este caso, la utilidad de línea de comandos
pep8
marca mi código:
La importación a nivel de módulo E402 no está en la parte superior del archivo
¿Cuál es la mejor manera de lograr el cumplimiento de
sys.path
con
sys.path
modificaciones de
sys.path
?
Por qué
Tengo este código porque estoy siguiendo la estructura del proyecto dada en la Guía del autoestopista de Python .
Esa guía sugiere que tengo una carpeta
my_module
, separada de una carpeta de
tests
, las cuales están en el mismo directorio.
Si quiero acceder a
my_module
desde las
tests
, creo que necesito agregar
..
al
sys.path
A menudo tengo varios archivos con pruebas en un subdirectorio
foo/tests
de mi proyecto, mientras que los módulos que estoy probando están en
foo/src
.
Para ejecutar las pruebas desde
foo/tests
sin errores de importación, creo un archivo
foo/tests/pathmagic.py
que se ve así;
"""Path hack to make tests work."""
import os
import sys
bp = os.path.dirname(os.path.realpath(''.'')).split(os.sep)
modpath = os.sep.join(bp + [''src''])
sys.path.insert(0, modpath)
En cada archivo de prueba, luego uso
import pathmagic # noqa
como la primera importación
El comentario "noqa" evita que
pycodestyle
/
pep8
queje de una importación no utilizada.
Acabo de luchar con una pregunta similar, y creo que encontré una solución un poco mejor que la respuesta aceptada.
Cree un módulo
pathmagic
que realice la manipulación sys.path real, pero realice el cambio dentro de un
administrador de contexto
:
"""Path hack to make tests work."""
import os
import sys
class context:
def __enter__(self):
bp = os.path.dirname(os.path.realpath(''.'')).split(os.sep)
modpath = os.sep.join(bp + [''src''])
sys.path.insert(0, modpath)
def __exit__(self, *args):
pass
Luego, en sus archivos de prueba (o donde lo necesite), usted hace:
import pathmagic
with pathmagic.context():
import my_module
# ...
De esta manera, no recibe ninguna queja de flake8 / pycodestyle, no necesita comentarios especiales y la estructura parece tener sentido.
Para una limpieza adicional, considere la posibilidad de revertir la ruta en el bloque
__exit__
, aunque esto puede causar problemas con las importaciones diferidas (si coloca el código del módulo fuera del contexto), por lo que tal vez no valga la pena.
EDITAR
: acabo de ver un truco mucho más simple en una
respuesta a una pregunta diferente
: agregue la
assert pathmagic
debajo de sus importaciones para evitar el comentario
noqa
.
Hay otra solución alternativa.
import sys
... all your other imports...
sys.path.insert("..", 0)
try:
import my_module
except:
raise
Para cumplir con pep8, debe incluir la ruta del proyecto a la ruta de Python para realizar importaciones relativas / absolutas.
Para hacerlo, puede echar un vistazo a esta respuesta: agregar permanentemente un directorio a PYTHONPATH
Si solo hay unas pocas importaciones, puede ignorar PEP8 en esas líneas de
import
:
import sys
sys.path.insert("..", 0)
import my_module # noqa: E402