Importação Python

Resumo : neste tutorial, você examinará as variantes da instrução de importação do Python e como elas funcionam nos bastidores.

módulo de importação

Quando você importa um módulo, o Python faz duas coisas:

  • Primeiro, verifique se o módulo foi carregado e armazenado em cache em sys.modules. Caso contrário, ele executará o módulo e criará uma referência ao objeto do módulo.
  • Segundo, adicione o nome do módulo ao namespace global que faz referência ao mesmo objeto de módulo.

O programa a seguir importa o módulo matemático e imprime o mathobjeto no sys.modulesnamespace global:

import sys
import math


print('sys.modules:', hex(id(sys.modules['math'])))

if 'math' in globals():
    print('globals: ', hex(id(globals()['math'])))Linguagem de código:  JavaScript  ( javascript )

Saída:

sys.modules: 0x20456766590
globals:  0x20456766590Linguagem de código:  HTTP  ( http )

Como você pode ver, a mathvariável faz referência ao mesmo objeto de módulo.

Se você importar um módulo pela segunda vez, o Python não executará o mathmódulo novamente, mas o obterá do sys.modulescache.

do objeto de importação do módulo

Quando você importa um objeto (uma função , uma classe , etc.,) de um módulo, o Python faz o seguinte:

  • Primeiro, verifique se o módulo foi carregado e armazenado em cache no arquivo sys.modules. Caso contrário, ele executará o módulo e criará uma referência ao objeto do módulo.
  • Segundo, adicione o objeto de importação ao namespace global.

Nesse caso, Python não adiciona uma variável que faz referência ao módulo ao namespace global, mas uma variável que faz referência ao objeto importado.

O exemplo a seguir importa a ceilfunção do mathobjeto:

import sys
from pprint import pprint
from math import ceil

print('sys.modules:', hex(id(sys.modules['math'])))

pprint(globals())
Linguagem de código:  JavaScript  ( javascript )

Saída:

sys.modules: 0x11d659c2130
{'__annotations__': {},
 '__builtins__': <module 'builtins' (built-in)>,
 '__cached__': None,
 '__doc__': None,
 '__file__': 'C:/oop/app.py',
 '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000011D65A008E0>,
 '__name__': '__main__',
 '__package__': None,
 '__spec__': None,
 'ceil': <built-in function ceil>,
 'pprint': <function pprint at 0x0000011D661C4040>,
 'sys': <module 'sys' (built-in)>}Linguagem de código:  PHP  ( php )

Neste exemplo, Python carrega o mathmódulo no arquivo sys.modules. No entanto, ele cria apenas uma referência à ceilfunção, não ao mathobjeto do módulo no namespace global.

do objeto de importação do módulo como object_alias

Quando você carrega um objeto de um módulo e usa um alias, o Python fará o seguinte:

  • Primeiro, verifique se o módulo foi carregado e armazenado em cache no arquivo sys.modules. Caso contrário, ele executará o módulo e criará uma referência ao objeto do módulo.
  • Segundo, crie um alias que faça referência ao objeto importado e adicione-o ao namespace global.

Por exemplo, o seguinte importa a ceilfunção do módulo matemático e usa o alias de teto:

import sys
from math import ceil as ceiling

print('sys.modules:', hex(id(sys.modules['math'])))
print('globals:', hex(id(globals()['ceiling'])))Linguagem de código:  JavaScript  ( javascript )

Saída:

sys.modules: 0x1cc4f244ae0
{'__annotations__': {},
 '__builtins__': <module 'builtins' (built-in)>,
 '__cached__': None,
 '__doc__': None,
 '__file__': 'C:/oop/app.py',
 '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001CC4EA708E0>,
 '__name__': '__main__',
 '__package__': None,
 '__spec__': None,
 'ceiling': <built-in function ceil>,
 'pprint': <function pprint at 0x000001CC4F234040>,
 'sys': <module 'sys' (built-in)>}Linguagem de código:  PHP  ( php )

da importação do módulo *

Ao importar tudo de um módulo, o Python fará o seguinte:

  • Primeiro, verifique se o módulo foi carregado e armazenado em cache em sys.modules. Caso contrário, ele executará o módulo e criará uma referência ao objeto do módulo.
  • Segundo, adicione todos os símbolos do módulo ao namespace global .

Por exemplo, o seguinte importa todos os objetos do módulo matemático:

import sys
from pprint import pprint
from math import *

print('sys.modules:', hex(id(sys.modules['math'])))
pprint(globals())Linguagem de código:  JavaScript  ( javascript )

Saída:

sys.modules: 0x1e1ebf24b30
{'__annotations__': {},
 '__builtins__': <module 'builtins' (built-in)>,
 '__cached__': None,
 '__doc__': None,
 '__file__': 'C:/oop/app.py',
 '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001E1EB7408E0>,
 '__name__': '__main__',
 '__package__': None,
 '__spec__': None,
 'acos': <built-in function acos>,
 'acosh': <built-in function acosh>,
 'asin': <built-in function asin>,

 ....
 'tau': 6.283185307179586,
 'trunc': <built-in function trunc>}Linguagem de código:  PHP  ( php )

Como você pode ver claramente na saída, Python adiciona todas as funções do módulo matemático aos namespaces globais. Nesse caso, se existir algum símbolo no namespace global, o Python substituirá suas referências.

Isso geralmente leva a bugs que são difíceis de rastrear. Portanto, você deve evitar usar o módulo from import *

Equívoco de importação de Python

Um dos equívocos mais comuns da declaração de importação é que muitos consideram a seguinte declaração:

from math import ceilLinguagem de código:  JavaScript  ( javascript )

é mais eficiente do que:

import mathLinguagem de código:  JavaScript  ( javascript )

Porque a primeira instrução importa apenas a ceilfunção, enquanto a segunda instrução importa o mathmódulo inteiro.

No entanto, o Python carrega o mathmódulo inteiro em ambos os casos.

A primeira instrução cria um símbolo que faz referência à ceilfunção do mathmódulo, enquanto a segunda instrução cria o mathsímbolo que faz referência ao mathobjeto do módulo.

Resumo

  • A instrução Python importcarrega um módulo apenas uma vez e o armazena em cache no arquivo sys.modules.
  • Evite usar o from module import *porque pode causar um bug.
  • Não use from module import objectpara otimizar a velocidade do programa porque isso não acontecerá.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *