Módulos

Prévio Próximo

Python Logo6. Modulos

Se você sair do interpretador Python e entrar novamente, as definições que você fez (funções e variáveis) são perdidas. Portanto, se você quer escrever um programa um pouco mais longo, é melhor você usar um editor de texto para preparar a entrada para o intérprete e executá-lo com esse arquivo como entrada em seu lugar. Isto é conhecido como a criação de um script. Tal como o seu programa fica maior, você pode querer dividi-lo em vários arquivos para facilitar a manutenção. Você também pode querer usar uma função útil que você escreveu em vários programas sem copiar sua definição em cada programa.
Para suportar isto, Python tem uma maneira de colocar as definições em um arquivo e usá-los em um script ou em uma instância interativa do intérprete. Esse arquivo é chamado de módulo; definições de um módulo podem ser importadas para outros módulos ou no módulo principal (a coleção de variáveis às ​​que você tem acesso em um script executado no nível superior e no modo de calculadora).Um módulo é um arquivo contendo definições e comandos Python. O nome do arquivo é o nome do módulo com o sufixo .py anexado. Dentro de um módulo, o nome do módulo (tal como uma cadeia de caracteres) está disponível como o valor da variável global __name__. Por exemplo, usar o seu editor de texto favorito para criar um arquivo chamado fibo.py no diretório atual com o seguinte conteúdo:
# Fibonacci numbers module

def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while b < n:
        print b,
        a, b = b, a+b

def fib2(n): # return Fibonacci series up to n
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a+b
    return result
Agora entre no interpretador Python e importe este módulo com o seguinte comando:
>>> import fibo
Isso não entra os nomes das funções definidas em fibo diretamente na tabela de símbolos corrente; apenas coloca o nome do módulo lá. Usando o nome do módulo, você pode acessar as funções:
>>> fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'
Se você pretende usar uma função, muitas vezes você pode atribuí-la a um nome local:
>>> fib = fibo.fib
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

6.1. Mais Sobre Módulos

Um módulo pode conter declarações executáveis, bem como definições de funções. Estas declarações têm a intenção de inicializar o módulo. Elas são executadas apenas na primeira vez que o nome do módulo é encontrado em uma declaração de importação. [1] (Elas também são executadas se o arquivo é executado como um script.)Cada módulo tem a sua própria tabela de símbolo privada, a qual é usada como a tabela de símbolo global por todas as funções definidas no módulo. Assim, o autor de um módulo pode utilizar variáveis globais no módulo sem se preocupar com os confrontos acidental com as variáveis globais de usuário. Por outro lado, se você sabe o que você está fazendo, você pode tocar as variáveis globais do módulo com a mesma notação usada para se referir às suas funções, modname.itemname.
Os módulos podem importar outros módulos. É costume, mas não são obrigados a colocar todas as declarações import no início de um módulo (ou script). Os nomes dos módulos importados são colocados na tabela de símbolo global do módulo importador.Existe uma variante da declaração import que importa nomes de um módulo diretamente na tabela de símbolos do módulo importador. Por exemplo:
>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
Isso não introduz o nome do módulo a partir do qual as importações são tomadas na tabela de símbolos local (assim, no exemplo, fibo não está definido).Existe ainda uma variante para importar todos os nomes que um módulo define:
>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
Isso importa todos os nomes, exceto aqueles que começam com um sublinhado (_).Note-se que, em geral, a prática de importar tudo a partir de um módulo ou pacote é desaprovada, uma vez que muitas vezes torna o código mal legível. No entanto, não há problema em usá-lo para salvar a digitação em sessões interativas.

Note:

Por razões de eficiência, cada módulo é só importado uma vez por sessão do interpretador. Portanto, se você mudar seus módulos, você deve reiniciar o interpretador – ou, se é apenas um módulo que você quer testar de forma interativa, use reload(), por exemplo, reload(nomedomodulo).

6.1.1. Executando Módulos Como Scripts

Quando voce executa um módulo Python com
python fibo.py <arguments>
o código no módulo será executado, exatamente como se você o tivesse importado, mas com o __name__ definido como “__main__“. Isso significa que, adicionando este código ao final do seu módulo:
if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))
você pode fazer o arquivo utilizável como um script, bem como um módulo importável, porque o código que analisa a linha de comando só será executado se o módulo é executado como o arquivo “main”:
$ python fibo.py 50
1 1 2 3 5 8 13 21 34
Se o módulo fôr importado, o código não será executado:
>>> import fibo
>>>
Isso é muitas vezes usado para fornecer uma interface de usuário conveniente para um módulo, ou para fins de teste (executando o módulo como um script executa um conjunto de testes).

6.1.2. O Módulo de Caminho de Pesquisa (Search Path)

Quando um módulo denominado spam é importado, o interpretador procura primeiro por um módulo embutido com esse nome. Se não for encontrado, então ele procura por um arquivo chamado spam.py em uma lista de diretórios dadas pela variável sys.path que é inicializada a partir destes locais:
  • O diretório que contém o script de entrada (ou o diretório atual).
  • PYTHONPATH (uma lista de nomes de diretório, com a mesma sintaxe que a variável PATH do shell).
  • O diretório padrão que depende da instalação.

Após a inicialização, programas Python podem modificar o sys.path. O diretório que contém o script que está sendo executado é colocado no início do caminho de procura (path), à frente do caminho da biblioteca padrão. Isto significa que os scripts neste diretório serão carregado em vez de módulos do mesmo nome no diretório da biblioteca. Este é um erro, a menos que a substituição seja intencional. Consulte a seção módulos padrão para mais informações.

6.1.3. Arquivos Python “Compilados”

Como um importante aumento de velocidade no tempo de início de programas curtos que utilizam uma grande quantidade de módulos padrão, se um arquivo chamado .pyc existe no diretório onde spam.py for encontrado, este é assumido para conter uma “versão byte-compilada” do módulo spam. O tempo de modificação da versão de spam.py usadas para criar .pyc é registrada em .pyc,  eo arquivo .pyc é ignorado, se estes não coincidem.Normalmente, você não precisa fazer nada para criar o arquivo .pyc. Sempre que spam.py é compilado com sucesso, é feita uma tentativa de escrever a versão compilada para .pyc. Não é gerado um erro se a tentativa falhar; Se por algum motivo o arquivo não fôr escrito completamente, o arquivo .pyc resultante será reconhecido como inválido e, portanto, ignorado. O conteúdo do arquivo .pyc é independente de plataforma, assim um diretório de módulos Python pode ser compartilhado por diferentes arquiteturas.

Algumas dicas dos experts:

  • Quando o interpretador Python é invocado com a opção -O, código otimizado é gerado e armazenado em arquivos .pyo. O otimizador atualmente não ajuda muito; ele apenas remove declarações assert. Quando -O é utilizado, todo bytecode é otimizado; arquivos .pyc são ignorados e arquivos .py são compilados para bytecode otimizado.
  • Passando dois flags -O ao interpretador Python (-oo) fará com que o compilador bytecode performe otimizações que poderia, em alguns casos raros, resultar em mal funcionamento de programas. Actualmente apenas __doc__ strings são removidas do bytecode, resultando em arquivos .pyo mais compactos. Uma vez que alguns programas confiem em ter estes disponíveis, você só deve usar esta opção se você souber o que está fazendo.
  • Um programa não funciona mais rápido quando é lido a partir de um arquivo .pyc ou .pyo do que quando ele é lido a partir de um arquivo .py; a única coisa que é mais rápido sobre os arquivos .pyc ou .pyo é a velocidade com que são carregados.
  • Quando um script é executado, dando o seu nome na linha de comando, o bytecode para o script nunca é gravado em um arquivo .pyc ou .pyo. Assim, o tempo de início de um script pode ser reduzido por mover a maioria do seu código para um módulo, e tendo um script bootstrap pequeno que importe aquele módulo. Também é possível citar arquivos  .pyc ou .pyo diretamente na linha de comando.
  • É possível ter um arquivo chamado .pyc (ou spam.pyo quando é usado -O) sem um arquivo spam.py para o mesmo módulo. Isto pode ser utilizado para distribuir uma biblioteca de código Python em uma forma que é moderadamente dura para a engenharia inversa.
  • O módulo compileall pode criar arquivos .pyc (ou arquivos .pyo quando é usado -O) para todos os módulos em um diretório.

6.2. Módulos Padrão

Python vem com uma biblioteca de módulos padrão, descrito em um documento separado, a Biblioteca de Referência Python (“Biblioteca de Referência” a seguir). Alguns módulos são construídos dentro do interpretador; estes fornecem acesso a operações que não fazem parte do núcleo da linguagem, mas são, no entanto, construídos dentro, seja por eficiência ou para fornecer acesso a primitivas do sistema operacional, tais como chamadas de sistema. O conjunto de tais módulos é uma opção de configuração que também depende da plataforma subjacente. Por exemplo, o módulo winreg é fornecido apenas em sistemas Windows. Um módulo especial merece alguma atenção: sys, que é construído em qualquer interpretador Python. As variáveis sys.ps1 e sys.ps2 através definem as strings utilizadas como prompt primário e secundário:
>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print 'Yuck!'
Yuck!
C>
Estas duas variáveis são definidas apenas se o interpretador estiver em modo interativo.A variável sys.path é uma lista de strings que determina caminho de pesquisa do intérprete para módulos. Ela é inicializada para um caminho default determinado pela variável de ambiente PYTHONPATH, ou a partir de um padrão default -se PYTHONPATH não estiver definida. Você pode modificá-la usando as operações de lista padrão:
>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')

6.3. A Função dir()

A função interna dir() é usada para descobrir quais nomes um módulo define. Ele retorna uma lista ordenada de strings:
>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)  
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__package__', 
'__stderr__', '__stdin__', '__stdout__', '_clear_type_cache', 
'_current_frames', '_getframe', '_mercurial', 'api_version', 'argv', 
'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 
'copyright', 'displayhook', 'dont_write_bytecode', 'exc_clear', 'exc_info', 
'exc_traceback', 'exc_type', 'exc_value', 'excepthook', 'exec_prefix', 
'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 
'getcheckinterval', 'getdefaultencoding', 'getdlopenflags', 
'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit', 
'getrefcount', 'getsizeof', 'gettotalrefcount', 'gettrace', 'hexversion', 
'long_info', 'maxint', 'maxsize', 'maxunicode', 'meta_path', 'modules', 
'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1', 
'py3kwarning', 'setcheckinterval', 'setdlopenflags', 'setprofile', 
'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'subversion', 
'version', 'version_info', 'warnoptions']
Sem argumentos, dir() lista os nomes que você definiu no momento:
>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir()
['__builtins__', '__name__', '__package__', 'a', 'fib', 'fibo', 'sys']
Note-se que ela lista todos os tipos de nomes: variáveis, módulos, funções, etc.A função dir() não lista os nomes de funções e variáveis internas. Se você quiser uma lista delas, elas estão definidas no  módulo padrão __builtin__:
>>> import __builtin__
>>> dir(__builtin__)  
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 
'BufferError', 'BytesWarning', 'DeprecationWarning', 'EOFError', 
'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 
'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 
'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 
'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented', 
'NotImplementedError', 'OSError', 'OverflowError', 
'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 
'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError', 
'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 
'TypeError', 'UnboundLocalError', 'UnicodeDecodeError',
 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 
'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 
'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__', 
'__name__', '__package__', 'abs', 'all', 'any', 'apply', 'basestring', 
'bin', 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr', 
'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'copyright', 
'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 
'execfile', 'exit', 'file', 'filter', 'float', 'format', 'frozenset', 
'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 
'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len', 'license', 
'list', 'locals', 'long', 'map', 'max', 'memoryview', 'min', 'next', 
'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 
'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round',
'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 
'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']

6.4. Pacotes (Packages)

Os pacotes são uma maneira de estruturar módulo namespace do Python usando “nomes pontilhados de módulos”. Por exemplo, o nome do módulo A.B designa um sub-módulo chamado B em um pacote chamado A. Assim como o uso de módulos de salva os autores de diferentes módulos de ter que se preocupar com nomes de variáveis globais ​​de cada um, o uso de nomes pontilhados de módulos salva os autores de pacotes multi-módulo como NumPy ou o Python Imaging Library de ter que se preocupar com os nomes de uns dos outros módulos.
Suponha que você queira criar uma coleção de módulos (um “pacote”) para o gerenciamento uniforme de arquivos de som e dados de som. Há muitos formatos diferentes de arquivo de som (geralmente reconhecidos pela sua extensão, por exemplo: .wav, .aiff, .au), assim você pode precisar para criar e manter uma crescente coleção de módulos para a conversão entre os vários formatos de arquivo. Há também muitas operações diferentes que você pode querer executar em dados de som (tais como mistura, acrescentando eco, a aplicação de uma função de equalizador, criando um efeito stereo artificial), de modo que, além disso você vai estar escrevendo um fluxo interminável de módulos para executar estas operações. Aqui está uma possível estrutura para o seu pacote (expressa em termos de um sistema de arquivos hierárquico):
sound/                          Top-level package
      __init__.py               Initialize the sound package
      formats/                  Subpackage for file format conversions
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  Subpackage for sound effects
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  Subpackage for filters
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...

Ao importar o pacote, Python procura através dos diretórios em sys.path procurando o subdiretório do pacote.Os arquivos __init__.py são obrigados para fazer Python tratar os diretórios como contendo pacotes; isto é feito para evitar diretórios com um nome comum, como string, de inadvertidamente esconder módulos válidos que ocorram mais tarde no caminho de pesquisa do módulo. No caso mais simples, __init__.py pode ser apenas um arquivo vazio, mas também pode executar um código de inicialização para o pacote ou definir a variável __all__, descrito mais tarde.Os utilizadores do pacote podem importar módulos individuais da embalagem, por exemplo:

import sound.effects.echo
Isso carrega o sub-módulo Sound.Effects.echo. Deve ser referenciado com o seu nome completo.
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
Uma forma alternativa de importar o sub-módulo é:
from sound.effects import echo
Isto também carrega o sub-módulo de eco, e o torna disponível sem o seu prefixo de pacote, de modo a poder ser utilizado como se segue:
echo.echofilter(input, output, delay=0.7, atten=4)
Ainda outra variação é importar a função ou variável desejada diretamente:
from sound.effects.echo import echofilter
Mais uma vez, deste modo carrega o sub-módulo eco, mas isso faz com que sua função echofilter() fique diretamente disponível:
echofilter(input, output, delay=0.7, atten=4)
Note-se que quando se utiliza from package import item, o item pode ser um sub-módulo (ou sub-pacote) do pacote, ou algum outro nome definido no pacote, como uma função, classe ou variável. A declaração import primeiro testa se o item está definido no pacote; se não, ela assume que é um módulo e tenta carregá-lo. Se ela não conseguir encontrá-lo, uma exceção ImportError é levantada.Ao contrário, quando usando a sintaxe como import item.subitem.subsubitem, cada item, exceto o último deve ser um pacote; o último item pode ser um módulo ou um pacote, mas não pode ser uma função ou classe ou variável definida no item anterior.

6.4.1. Importando * de um Pacote

Agora o que acontece quando o usuário escreve from sound.effects import *? Idealmente, seria de se esperar que isso de alguma forma vai para o sistema de arquivos, acha que sub-módulos estão presentes no pacote, e importa todos eles. Isso pode levar um longo tempo e importação de sub-módulos pode ter efeitos colaterais indesejados que só deve acontecer quando o sub-módulo é explicitamente importado.A única solução é o autor do pacote fornecer um índice explícito do pacote. A declaração import utiliza a seguinte convenção: se o código __init__.py de um pacote define uma lista chamada __all__, ela é considerada como sendo a lista de nomes de módulos que devem ser importados quando from package import * é encontrado. Cabe ao autor do pacote manter esta lista atualizada, quando uma nova versão do pacote é liberado. Autores de pacotes também podem decidir não apoiá-lo, se não virem um uso para a import * do seu pacote. Por exemplo, o arquivo sound/effects/__ init__.py poderia conter o seguinte código:
__all__ = ["echo", "surround", "reverse"]
Isto significa que a partir de sound.effects import * iria importar apenas os três sub-módulos chamados do pacote sound.Se __all__ não for definido, a declaração from sound.effects import * não importa todos os sub-módulos do pacote sound.effects para o namespace atual; ele só garante que o pacote sound.effects foi importado (possivelmente executa qualquer código de inicialização em __init__.py) e, em seguida, importa quaisquer dos nomes definidos no pacote. Isso inclui todos os nomes definidos (e sub-módulos explicitamente carregados) por __init__.py. Ele também inclui quaisquer sub-módulos do pacote que foram explicitamente carregado por declarações import anteriores. Considere o seguinte código:
import sound.effects.echo
import sound.effects.surround
from sound.effects import *

Neste exemplo, os módulos echo e surround são importados para o namespace atual, porque eles são definidos no pacote sound.effects quando a declaração import … é executada. (Isto também funciona quando __all__ está definido.)Embora alguns módulos são projetados para exportar apenas os nomes que seguem determinados padrões quando você usa import *, ainda é considerado uma má prática no código de produção.Lembre-se, não há nada de errado com o uso de from Package import specific_submodule ! Na verdade, esta é a notação recomendada a menos que o módulo de importação precise utilizar sub-módulos com o mesmo nome vindos de diferentes pacotes.

6.4.2. Referências Inter-Pacotes (Intra-Package)

Os sub-módulos frequentemente precisam referenciar uns aos outros. Por exemplo, o módulo surround pode utilizar o módulo echo. Na verdade, essas referências são tão comuns que a declaração import olha primeiramente no pacote antes de procutrar no caminho de procura padrão de módulos (standard module search path). Assim, o módulo surround pode usar simplesmente import echo ou from echo import echofilter. Se o módulo importado não fôr encontrado no pacote corrente (o pacote do qual o módulo atual é um sub-módulo), a declaração import procura por um módulo de nível superior com o nome dado.
Quando pacotes são estruturados em subpacotes (como com o pacote de som no exemplo), você pode usar as importações absolutas para se referir a submódulos de pacotes irmãos. Por exemplo, se o módulo sound.filters.vocoder precisar de usar o módulo echo no pacote sound.effects, pode utilizar from sound.effects import echo.
Começando com Python 2.5, além das importações implícitas relativas descritas acima, você pode escrever importações explícitaa relativas da forma from module import name da declaração import. Estas importações relativas explícitas usam pontos principais para indicar os pacotes atuais e pais envolvidos na importação relativa. A partir do módulo surround por exemplo, você pode usar
from . import echo
from .. import formats
from ..filters import equalizer
Note-se que tanto as importações relativas explícitas e implícitas são baseadas no nome do módulo atual. Uma vez que o nome do módulo principal é sempre “__main__“, módulos destinados a serem utilizados como o módulo principal de uma aplicação Python devem usar sempre importações absolutas.

6.4.3. Pacotes em Vários Diretórios

Pacotes suportam mais um atributo especial, o __path__. Este é inicializado para ser uma lista contendo o nome do diretório que contem o __init__.py do pacote antes que o código daquele arquivo seja executado. Esta variável pode ser modificada; isso afeta futuras pesquisas de módulos e sub-módulos contidos no pacote.Embora esta característica não é muitas vezes necessária, ela pode ser usada para estender o conjunto de módulos encontrados num pacote.

Notas de Rodapé

[1] Na verdade definições de funções são também “declarações” que são “executadas”; a execução de uma definição de função de nível de módulo entra o nome da função na tabela símbolo global do módulo.
Prévio Próximo