2012-01-27 13 views
6

En caso de duda, coloco mis declaraciones de importación en la parte superior del módulo. A menudo, esto reduce la repetición, lo cual es bueno. Sin embargo, ¿hay una desventaja en el rendimiento en el caso donde solo una función (o clase) requiere la importación?Importación de Python en el nivel de función VS. Módulo nivel

¿Importar solo lo siguiente cuando se llama a la función?

 def func(): 
     from task import test 

Si es así, me imagino que podría ser una ligera eficiencia. También supongo que podría obtener algunos puntos adicionales para una recolección de basura más rápida y un alcance variable, ya que los objetos importados no se agregarían al diccionario global. Como otro cartel muy bien puesto:

Esto se debe principalmente a la búsqueda variable. Buscar una variable en el ámbito global requiere una búsqueda de diccionario. Por el contrario, el compilador determina los nombres locales estáticamente y los referencia por índice, por lo que no se requiere buscar el diccionario.

¿Son esas suposiciones justas que estoy totalmente fuera de base?

Gracias

+2

En cuanto al rendimiento de búsqueda de nombre: ** No importa. ** En el caso raro que lo haga, sabrá cuándo ha terminado el código, descubrió que es demasiado lento y tiene un perfil. – delnan

Respuesta

4

Una importación en una función solo se importa cuando se ejecuta la función. Tenga en cuenta que en Python, todas las declaraciones se ejecutan cuando se encuentran, y las importaciones son declaraciones como cualquier otra cosa. Las importaciones de nivel superior se importan cuando se importa el módulo, porque son declaraciones de nivel superior en el módulo.

Sus inquietudes sobre la búsqueda de nombres están mal orientadas: la diferencia es insignificante, y solo debe considerarse si el perfil muestra un problema.

Solo importo módulos en el alcance de la función por dos razones: 1) para solucionar problemas circulares de importación, que probablemente podrían resolverse de otra forma por refactorización, o 2) si el módulo es opcional, y la función no es utilizado por muchos de mis usuarios. En el caso de 2), el módulo puede faltar por completo y no habrá ningún problema a menos que alguien invoque la función.

+0

Esto fue más una pregunta teórica. Parece que hay una diferencia, incluso si es insignificante. Gracias Ned – Ben

+0

¿Es esa la manera más pitónica? Veo que algunas personas realizan importaciones en __init__.py en la raíz de su módulo e importan todo desde allí. ¿Se puede usar para resolver ciertas importaciones circulares? – radtek

3

Veamos lo que el código de bytes se vería como para las siguientes dos funciones:

def func1(): 
    """ test imported each time function is run """ 
    from task import test 
    test() 

def func2(): 
    """ test was imported at top of module """ 
    test() 

Como se puede ver a continuación, func2() ahorra un montón de pasos mediante el uso de la test función importada a nivel mundial .

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

    4   16 LOAD_FAST    0 (test) 
      19 CALL_FUNCTION   0 
      22 POP_TOP 
      23 LOAD_CONST    3 (None) 
      26 RETURN_VALUE 
>>> dis.dis(func2) 
    3   0 LOAD_GLOBAL    0 (test) 
       3 CALL_FUNCTION   0 
       6 POP_TOP 
       7 LOAD_CONST    1 (None) 
      10 RETURN_VALUE 

Teniendo esto en cuenta en la delantera es probablemente la optimización prematura, como se señala en el comentario de delnan.

En cuanto al espacio de nombres global, es poco probable que cause problemas de búsqueda. La forma más notable que creo que podría ver esto es si hubo una colisión hash para test y otro nombre que usa muy a menudo, lo que provocó que la búsqueda de ese segundo nombre llevara más tiempo. Una vez más, optimización prematura para considerar ese raro caso por adelantado.

+1

Pero tenga en cuenta que en realidad no importará el módulo más de una vez, simplemente verifica si tiene cada vez que se lo llama. – delnan

+0

Gracias por explicarlo así; Es útil. No estaba familiarizado con la biblioteca de dis. – Ben

0

Creo que tiene sentido colocar la importación en la definición si no se va a llamar con mucha frecuencia.

Cuestiones relacionadas