2009-07-27 13 views
48

Supongamos que tengo un módulo relativamente largo, pero necesito un módulo o método externo solo una vez.Práctica buena o mala en Python: importe en el medio de un archivo

¿Se considera correcto importar ese método o módulo en el medio del módulo?

O debería estar import s solo en la primera parte del módulo.

Ejemplo:

import string, pythis, pythat 
... 
... 
... 
... 
def func(): 
    blah 
    blah 
    blah 
    from pysomething import foo 
    foo() 
    etc 
    etc 
    etc 
... 
... 
... 

Por favor, justifique su respuesta y añadir enlaces a PEP s o fuentes pertinentes

+0

duplicado posible de [Python - importación en caso de] (http://stackoverflow.com/questions/12860841/python-import-in-if) – Abhijeet

Respuesta

48

PEP 8 afirma con autoridad:

importaciones siempre se colocan en la parte superior de el archivo, justo después de cualquier módulo comentarios y cadenas de documentación, y antes de variables globales del módulo y constantes.

PEP 8 debe ser la base de cualquier guía de estilo "en la casa", ya que resume lo que el equipo de Python subyacente se ha encontrado que el estilo más eficaz, en general (y con la disidencia individuo por supuesto, como en cualquier otro idioma, pero el consenso y BDFL acuerdan PPE 8).

+1

Alex: es una "mejor práctica" pero no siempre evitable. Vea el ejemplo que di más arriba. – jkp

+0

@jkp, S.Lott comentó su respuesta y mostró por qué ES evitable en ese ejemplo. Los únicos ejemplos en los que puedo pensar serían usar nombres de módulos generados dinámicamente, por lo tanto '__import__', no importados * en aquellos * casos que no puede importar hasta que sepa el nombre del módulo que está importando, pero luego no estás usando una 'importación' simple en él. –

+0

@ S.Lott "Abajo" :) – Draemon

7

Se considera "buena forma" para agrupar todas las importaciones juntos en el inicio del archivo .

Los módulos pueden importar otros módulos. Es habitual, pero no obligatorio, colocar todas las declaraciones de importación al comienzo de un módulo (o script, para el caso). Los nombres de los módulos importados se colocan en la tabla de símbolos globales del módulo de importación.

A partir de aquí: http://docs.python.org/tutorial/modules.html

8

Por lo general se considera una mala práctica, pero a veces es inevitable (por ejemplo cuando se tiene que evitar una importación circular).

Un ejemplo de un tiempo cuando es necesario: uso Waf para construir todo nuestro código. El sistema se divide en herramientas, y cada herramienta se implementa en su propio módulo. Cada módulo de herramienta puede implementar un método detect() para detectar si los prerrequisitos están presentes. Un ejemplo de uno de estos puede hacer lo siguiente:

def detect(self): 
    import foobar 

Si esto funciona correctamente, la herramienta es utilizable. Luego, más adelante en el mismo módulo, puede ser necesario el módulo foobar, por lo que deberá importarlo de nuevo, a nivel de nivel de función. Claramente, si se importó a nivel de módulo las cosas explotarían por completo.

+8

La importación dentro de la definición es ciertamente evitable. Usamos 'try: import x; excepto los bloques lógicos ImportError' para mantener todas las importaciones por adelantado. –

+0

Particularmente hice +1 en la parte sobre importación circular, aunque estoy de acuerdo con la respuesta de todos los demás sobre PEP8. Claro, las importaciones circulares pueden y deben ser corregidas, pero eso puede ser un esfuerzo inútil.Por lo tanto, con el interés de aportar valor con su tiempo, una importación en línea es aceptable si A) los cambios necesarios para evitar la importación en línea son altamente riesgosos para algún servicio en vivo, y | o B) la fijación de la importación circular no aporta ningún valor al usuario final (incluido en el largo plazo re: mantenimiento). Quizás, también C) porque lleva demasiado tiempo Y tiene un valor dudoso. – ThatsAMorais

10

Si el módulo importado se utiliza con poca frecuencia y la importación es costosa, la importación en el medio es correcta.

De lo contrario, es aconsejable seguir la sugerencia de Alex Martelli.

2

PEP8:

importaciones siempre se colocan en la parte superior de el archivo, justo después de cualquier módulo comentarios y cadenas de documentación, y antes de variables globales del módulo y constantes.

No es una mala práctica tener importaciones con alcance. De modo que la importación solo se aplica a la función en la que la usó.

Creo que el código sería más legible, aunque si las importaciones se agrupan juntas en la parte superior del bloque o si lo quiere globalmente en la parte superior del archivo.

2

Bueno, yo creo que es una buena práctica para agrupar todas las importaciones, junto al comienzo del archivo, ya todo el mundo sabe dónde buscar si quiere saber qué bibliotecas se cargan

15

Hubo una discusión detallada de este tema en el Python lista de correo en 2001:

https://mail.python.org/pipermail/python-list/2001-July/071567.html

+3

Votando esto para proporcionar un enlace a una discusión, en lugar de solo "dice PEP 8 asi que". Yo diría que la "carne" de esto comienza varios mensajes en el hilo (http://mail.python.org/pipermail/python-list/2001-July/097866.html). –

+5

Los enlaces anteriores están muertos, pero este parece funcionar: https://mail.python.org/pipermail/python-list/2001-July/071567.html Parte del debate puede ser eliminado. – jtpereyda

+2

Esta es una respuesta de solo enlace y no es útil. Pon la carne de tu respuesta aquí en su lugar. – Jess

6

95% de las veces, se debe poner todas sus importaciones en la parte superior del archivo. Un caso donde es posible que desee realizar una importación de función local es si tiene que hacerlo para evitar importaciones circulares. Digamos que foo.py importa bar.py, y una función en bar.py necesita importar algo de foo.py. Si coloca todas sus importaciones en la parte superior, podría tener problemas inesperados al importar archivos que se basan en información que aún no se ha compilado. En este caso, tener una función de importación local puede permitir que su código se mantenga detenido al importar el otro módulo hasta que su código haya sido completamente compilado, y usted llame a la función correspondiente.

Sin embargo, parece que su caso de uso se trata más bien de dejar claro de dónde viene foo(). En este caso, yo preferiría ahora una de dos cosas:

En primer lugar, en vez de

from prerequisite import foo 

requisito previo de importación directa, y más adelante se refieren a ella como prerequisite.foo. La verbosidad agregada se paga a sí misma gracias al aumento de la transparencia del código.

Alternativamente, (o junto con el anterior) si realmente es una distancia tan larga entre su importación y el lugar donde se está utilizando, es posible que su módulo sea demasiado grande. La necesidad de una importación que nada más use podría ser una indicación de un lugar donde su código podría ser refactorizado en un pedazo de tamaño más manejable.

+3

La circularidad se puede arreglar mediante la descomposición. Las importaciones condicionales son, en el mejor de los casos, una solución torpe. Yo diría que es el 99.7% del tiempo y el 0.3% es "hasta que puedas descomponerte para arreglar la circularidad". –

14

Todos los demás ya han mencionado los PEP, pero también tienen cuidado al no a tienen sentencias de importación en medio del código crítico. Al menos bajo Python 2.6, hay varias instrucciones más de bytecode requeridas cuando una función tiene una declaración de importación.

>>> def f(): 
    from time import time 
    print time() 

>>> dis.dis(f) 
    2   0 LOAD_CONST    1 (-1) 
       3 LOAD_CONST    2 (('time',)) 
       6 IMPORT_NAME    0 (time) 
       9 IMPORT_FROM    0 (time) 
      12 STORE_FAST    0 (time) 
      15 POP_TOP    

    3   16 LOAD_FAST    0 (time) 
      19 CALL_FUNCTION   0 
      22 PRINT_ITEM   
      23 PRINT_NEWLINE  
      24 LOAD_CONST    0 (None) 
      27 RETURN_VALUE 

>>> def g(): 
    print time() 

>>> dis.dis(g) 
    2   0 LOAD_GLOBAL    0 (time) 
       3 CALL_FUNCTION   0 
       6 PRINT_ITEM   
       7 PRINT_NEWLINE  
       8 LOAD_CONST    0 (None) 
      11 RETURN_VALUE 
Cuestiones relacionadas