Get started learning Python with DataCamp's free Intro to Python tutorial. Learn Data Science by completing interactive coding challenges and watching videos by expert instructors. Start Now!
This site is generously supported by DataCamp. DataCamp offers online interactive Python Tutorials for Data Science. Join 11 million other learners and get started learning Python for data science today!
Good news! You can save 25% off your Datacamp annual subscription with the code LEARNPYTHON23ALE25 - Click here to redeem your discount
Módulos e Pacotes
Em programação, um módulo é um pedaço de software que possui uma funcionalidade específica. Por exemplo, ao construir um jogo de ping pong, um módulo pode ser responsável pela lógica do jogo, e outro módulo desenha o jogo na tela. Cada módulo consiste em um arquivo diferente, que pode ser editado separadamente.
Escrevendo módulos
Módulos em Python são apenas arquivos Python com a extensão .py. O nome do módulo é o mesmo que o nome do arquivo. Um módulo Python pode ter um conjunto de funções, classes ou variáveis definidas e implementadas. O exemplo acima inclui dois arquivos:
mygame/
-
mygame/game.py
-
mygame/draw.py
O script Python game.py
implementa o jogo. Ele usa a função draw_game
do arquivo draw.py
,
ou em outras palavras, o módulo draw
que implementa a lógica para desenhar o jogo na tela.
Módulos são importados de outros módulos usando o comando import
. Neste exemplo, o script game.py
pode
parecer algo assim:
# game.py
# import the draw module
import draw
def play_game():
...
def main():
result = play_game()
draw.draw_game(result)
# this means that if this script is executed, then
# main() will be executed
if __name__ == '__main__':
main()
O módulo draw
pode parecer algo assim:
# draw.py
def draw_game():
...
def clear_screen(screen):
...
Neste exemplo, o módulo game
importa o módulo draw
, o que lhe permite usar funções implementadas
nesse módulo. A função main
usa a função local play_game
para executar o jogo, e então
desenha o resultado do jogo usando uma função implementada no módulo draw
chamada draw_game
. Para usar
a função draw_game
do módulo draw
, precisamos especificar em qual módulo a função está
implementada, usando o operador ponto. Para referenciar a função draw_game
do módulo game
,
precisamos importar o módulo draw
e então chamar draw.draw_game()
.
Quando a diretiva import draw
é executada, o interpretador Python procura um arquivo no diretório em que o script foi executado com o nome do módulo e um sufixo .py
. Neste caso, ele procurará por draw.py
. Se for encontrado, será importado. Se não for encontrado, continuará procurando por módulos embutidos.
Você pode ter notado que, ao importar um módulo, um arquivo .pyc
é criado. Este é um arquivo Python compilado.
Python compila arquivos em bytecode Python para que não precise parsear os arquivos cada vez que os módulos são carregados. Se um arquivo .pyc
existir, ele será carregado em vez do arquivo .py
. Este processo é transparente para o usuário.
Importando objetos de módulo para o namespace atual
Um namespace é um sistema onde cada objeto é nomeado e pode ser acessado em Python. Importamos a função draw_game
para o namespace do script principal usando o comando from
.
# game.py
# import the draw module
from draw import draw_game
def main():
result = play_game()
draw_game(result)
Você pode ter notado que neste exemplo, o nome do módulo não precede draw_game
, porque especificamos o nome do módulo usando o comando import
.
As vantagens desta notação é que você não precisa referenciar o módulo repetidamente. No entanto, um namespace não pode ter dois objetos com o mesmo nome, então o comando import
pode substituir um objeto existente no namespace.
Importando todos os objetos de um módulo
Você pode usar o comando import *
para importar todos os objetos de um módulo assim:
# game.py
# import the draw module
from draw import *
def main():
result = play_game()
draw_game(result)
Isso pode ser um pouco arriscado, já que mudanças no módulo podem afetar o módulo que importa, mas é mais curto, e não requer que você especifique cada objeto que deseja importar do módulo.
Nome de importação personalizado
Módulos podem ser carregados com qualquer nome que você quiser. Isso é útil ao importar um módulo condicionalmente para usar o mesmo nome no resto do código.
Por exemplo, se você tem dois módulos draw
com nomes ligeiramente diferentes, você pode fazer o seguinte:
# game.py
# import the draw module
if visual_mode:
# in visual mode, we draw using graphics
import draw_visual as draw
else:
# in textual mode, we print out text
import draw_textual as draw
def main():
result = play_game()
# this can either be visual or textual depending on visual_mode
draw.draw_game(result)
Inicialização do Módulo
A primeira vez que um módulo é carregado em um script Python em execução, ele é inicializado executando o código no módulo uma vez. Se outro módulo em seu código importar o mesmo módulo novamente, ele não será carregado novamente, então variáveis locais dentro do módulo atuam como um "singleton", significando que são inicializadas apenas uma vez.
Você pode então usar isso para inicializar objetos. Por exemplo:
# draw.py
def draw_game():
# when clearing the screen we can use the main screen object initialized in this module
clear_screen(main_screen)
...
def clear_screen(screen):
...
class Screen():
...
# initialize main_screen as a singleton
main_screen = Screen()
Estendendo o caminho de carregamento do módulo
Existem algumas maneiras de informar ao interpretador Python onde procurar módulos, além do
diretório local padrão e módulos embutidos. Você pode usar a variável de ambiente PYTHONPATH
para especificar diretórios adicionais para procurar módulos assim:
PYTHONPATH=/foo python game.py
Isso executa game.py
, e permite que o script carregue módulos do diretório foo
, bem como do diretório local.
Você também pode usar a função sys.path.append
. Execute-a antes de executar o comando import
:
sys.path.append("/foo")
Agora o diretório foo
foi adicionado à lista de caminhos onde os módulos são procurados.
Explorando módulos embutidos
Confira a lista completa de módulos embutidos na biblioteca padrão do Python aqui.
Duas funções muito importantes são úteis quando se explora módulos em Python - as funções dir
e help
.
Para importar o módulo urllib
, que nos permite criar e ler dados de URLs, nós importamos
o módulo:
# import the library
import urllib
# use it
urllib.urlopen(...)
Podemos ver quais funções são implementadas em cada módulo usando a função dir
:
>>> import urllib
>>> dir(urllib)
['ContentTooShortError', 'FancyURLopener', 'MAXFTPCACHE', 'URLopener', '__all__', '__builtins__',
'__doc__', '__file__', '__name__', '__package__', '__version__', '_ftperrors', '_get_proxies',
'_get_proxy_settings', '_have_ssl', '_hexdig', '_hextochr', '_hostprog', '_is_unicode', '_localhost',
'_noheaders', '_nportprog', '_passwdprog', '_portprog', '_queryprog', '_safe_map', '_safe_quoters',
'_tagprog', '_thishost', '_typeprog', '_urlopener', '_userprog', '_valueprog', 'addbase', 'addclosehook',
'addinfo', 'addinfourl', 'always_safe', 'basejoin', 'c', 'ftpcache', 'ftperrors', 'ftpwrapper', 'getproxies',
'getproxies_environment', 'getproxies_macosx_sysconf', 'i', 'localhost', 'main', 'noheaders', 'os',
'pathname2url', 'proxy_bypass', 'proxy_bypass_environment', 'proxy_bypass_macosx_sysconf', 'quote',
'quote_plus', 'reporthook', 'socket', 'splitattr', 'splithost', 'splitnport', 'splitpasswd', 'splitport',
'splitquery', 'splittag', 'splittype', 'splituser', 'splitvalue', 'ssl', 'string', 'sys', 'test', 'test1',
'thishost', 'time', 'toBytes', 'unquote', 'unquote_plus', 'unwrap', 'url2pathname', 'urlcleanup', 'urlencode',
'urlopen', 'urlretrieve']
Quando encontramos a função no módulo que queremos usar, podemos ler mais sobre ela com a função help
, usando o interpretador Python:
help(urllib.urlopen)
Escrevendo pacotes
Pacotes são namespaces contendo múltiplos pacotes e módulos. Eles são apenas diretórios, mas com certos requisitos.
Cada pacote em Python é um diretório que DEVE conter um arquivo especial chamado __init__.py
. Este arquivo, que pode estar vazio, indica que o diretório onde ele está é um pacote Python. Dessa forma, ele pode ser importado da mesma forma que um módulo.
Se criarmos um diretório chamado foo
, que marca o nome do pacote, podemos então criar um módulo dentro desse
pacote chamado bar
. Em seguida, adicionamos o arquivo __init__.py
dentro do diretório foo
.
Para usar o módulo bar
, podemos importá-lo de duas maneiras:
import foo.bar
ou:
from foo import bar
No primeiro exemplo acima, precisamos usar o prefixo foo
sempre que acessarmos o módulo bar
. No segundo exemplo, não precisamos, porque importamos o módulo para o namespace do nosso módulo.
O arquivo __init__.py
também pode decidir quais módulos o pacote exporta como a API, enquanto mantém outros módulos internos, sobrescrevendo a variável __all__
assim:
__init__.py:
__all__ = ["bar"]
Exercício
Neste exercício, imprima uma lista ordenada alfabeticamente de todas as funções no módulo re
que contêm a palavra find
.
import re
# Your code goes here
find_members = []
import re
# Your code goes here
find_members = []
for member in dir(re):
if "find" in member:
find_members.append(member)
print(sorted(find_members))
test_object('find_members')
success_msg('Great work!')
This site is generously supported by DataCamp. DataCamp offers online interactive Python Tutorials for Data Science. Join over a million other learners and get started learning Python for data science today!