módulos


Módulos, try-except-raise e outros

modulos

Programas em Python são salvos em arquivos com terminação ".py" Além de programas podemos também armazenar nesta forma funções ou coleções de funções.
Coleções de funções salvas em arquivos .py são chamadas de módulos (modules).
Coleções de módulos podem ser agrupadas em bibliotecas chamadas de packages (pacotes).
O Python dispões de uma vasta coleção de módulos, centenas se não milhares deles em domínio público. Estes módulos são resultado do trabalho voluntário de milhares de programadores e especialistas nas mais diversas áreas do conhecimento. Mais detalhes sobre módulos podem ser vistos na documentação oficial do Python.
Para saber quais packages já estão instalados em sua máquina você pode usar o seguinte comando:
In [1]:
import pip
sorted(["%s==%s" % (i.key, i.version) for i in pip.get_installed_distributions()])
Out[1]:
['adodbapi==2.6.0.7',
 'alabaster==0.7.6',
 'anaconda-client==1.2.1',
 'argcomplete==1.0.0',
 'astropy==1.0.6',
 'babel==2.1.1',
 'beautifulsoup4==4.4.1',
 'bitarray==0.8.1',
 'blaze==0.8.3',
 'bokeh==0.10.0',
 'boto==2.38.0',
 'bottleneck==1.0.0',
 'cffi==1.2.1',
 'clyent==1.2.0',
 'colorama==0.3.3',
 'comtypes==1.1.2',
 'conda-build==1.18.2',
 'conda-env==2.4.5',
 'conda==4.0.5',
 'configobj==5.0.6',
 'cryptography==1.0.1',
 'cssselect==0.9.1',
 'cycler==0.9.0',
 'cython==0.23.4',
 'cytoolz==0.7.4',
 'datashape==0.4.7',
 'decorator==4.0.4',
 'docutils==0.12',
 'dynd==5a2f274',
 'fastcache==1.0.2',
 'flask==0.10.1',
 'greenlet==0.4.9',
 'h5py==2.5.0',
 'html2text==2016.1.8',
 'idna==2.0',
 'ipykernel==4.1.1',
 'ipython-genutils==0.1.0',
 'ipython==4.0.1',
 'ipywidgets==4.1.0',
 'itsdangerous==0.24',
 'jdcal==1.0',
 'jedi==0.9.0',
 'jinja2==2.8',
 'jsonschema==2.4.0',
 'jupyter-client==4.1.1',
 'jupyter-console==4.0.3',
 'jupyter-core==4.0.6',
 'jupyter==1.0.0',
 'llvmlite==0.8.0',
 'lxml==3.4.4',
 'markupsafe==0.23',
 'matplotlib==1.5.0',
 'mechanize==0.2.5',
 'menuinst==1.3.2',
 'mistune==0.7.1',
 'multipledispatch==0.4.8',
 'nbconvert==4.0.0',
 'nbformat==4.0.1',
 'networkx==1.10',
 'nltk==3.1',
 'nose==1.3.7',
 'notebook==4.0.6',
 'numba==0.22.1',
 'numexpr==2.4.4',
 'numpy==1.11.0',
 'oauthlib==1.0.3',
 'odo==0.3.4',
 'openpyxl==2.2.6',
 'pandas==0.17.1',
 'path.py==0.0.0',
 'patsy==0.4.0',
 'pep8==1.6.2',
 'pickleshare==0.5',
 'pillow==3.0.0',
 'pip==8.1.1',
 'ply==3.8',
 'psutil==3.3.0',
 'py==1.4.30',
 'pyasn1==0.1.9',
 'pycosat==0.6.1',
 'pycparser==2.14',
 'pycrypto==2.6.1',
 'pycurl==7.19.5.1',
 'pyflakes==1.0.0',
 'pygments==2.0.2',
 'pymc==2.3.6',
 'pymongo==3.2.1',
 'pyopenssl==0.15.1',
 'pyparsing==2.0.3',
 'pyperclip==1.5.27',
 'pyreadline==2.1',
 'pytagcloud==0.3.5',
 'pytest==2.8.1',
 'python-dateutil==2.4.2',
 'pytz==2015.7',
 'pywin32==219',
 'pyyaml==3.11',
 'pyzmq==14.7.0',
 'qtconsole==4.1.1',
 'requests-oauthlib==0.6.0',
 'requests==2.9.1',
 'robobrowser==0.5.3',
 'rope-py3k==0.9.4.post1',
 'scikit-image==0.11.3',
 'scikit-learn==0.17',
 'scipy==0.17.0',
 'seaborn==0.7.0',
 'selenium==2.52.0',
 'send2trash==1.3.0',
 'setuptools==20.7.0',
 'simplegeneric==0.8.1',
 'six==1.10.0',
 'snowballstemmer==1.2.0',
 'sockjs-tornado==1.0.1',
 'sphinx-rtd-theme==0.1.7',
 'sphinx==1.3.1',
 'spyder==2.3.8',
 'sqlalchemy==1.0.9',
 'statsmodels==0.6.1',
 'sympy==0.7.6.1',
 'tables==3.2.2',
 'theano==0.8.1',
 'toolz==0.7.4',
 'tornado==4.3',
 'traitlets==4.0.0',
 'tweepy==3.5.0',
 'twython==3.4.0',
 'ujson==1.33',
 'unicodecsv==0.14.1',
 'werkzeug==0.11.2',
 'wheel==0.29.0',
 'xlrd==0.9.4',
 'xlsxwriter==0.7.7',
 'xlwings==0.5.0',
 'xlwt==1.0.0']
Como saber quais pacotes existem disponíveis? Uma lista de packages pode ser vista aqui. Entretanto na prática é mais fácil consultar o Google com palavras chave "Python o_que_quero_fazer". Provavelmente alguem já teve sua dúvida e postou informação e pistas.
Quando você instalou Anaconda um monte de packages vieram junto. Neste curso precisaremos ocasionalmente de pacotes que não tenham sido instalados, neste caso a instalação manual é a solução. Se um package desejado não estiver instalado em sua máquina você pode instalar usando o comando
pip install pacote_desejado

Para um dado módulo ou package ser útil é necessário verificar em sua documentação quais as funções incluidas e como usá-las.
Módulos podem ser importados por outros programas ou módulos, usando o comando import seguido do nome do módulo a ser importado. Uma vez importado um módulo todas as suas funções ficam habilitadas para chamadas dentro do programa que as importou. A sintaxe genérica para tais chamadas é nome_do_modulo.nome_da_função().
Existem dois modos de importar um módulo ou só parte de suas funções. A maneira de importar tudo que o módulo contem é usar o comando import seguido do nome do módulo. Por exemplo um módulo importante é chamado os.py e contém muitas funções para manipular o sistema operacional, diretórios e arquivos. Usamos êle em muitos scripts Python. Eis como importá-lo:
In [3]:
import os

# note que se omite a terminação ".py" no comando acima
# Tendo importado os.py posso chamar suas funções. Por exe. qual é nosso diretório atual?
os.getcwd()
Out[3]:
'C:\\Users\\ps\\Desktop\\Blog'
O módulo os.py contém muitos objetos os quais tem métodos (funções associadas) que podem ser chamados por sua vez. Por exemplo um objeto interno é o path o qual contém muitas funções úteis para manipular caminhos na estrutura de diretórios.
In [6]:
s = os.getcwd()      # caminho do diretório atual
nome = 'rule.html'   # nome de um arquivo que deveria estar aqui

# quero ver se este arquivo existe neste diretório
# primeiro formo um caminho até ele
fpath = os.path.join(s,nome)
print(fpath)
print()              # imprime linha em branco para maior clareza

# agora uso outra função do os: testa se fpath é um arquivo ou não
if os.path.isfile(fpath):
    print('Arquivo ' + nome + ' existe.')
else:
    print('Arquivo não encontrado.')
C:\Users\ps\Desktop\Blog\rule.html

Arquivo rule.html existe.

A outra forma de importar funções é quando não queremos importar um módulo inteiro mas somente uma ou algumas das funções do módulo. Isto pode ser útil quando importamos muitos módulos num script e queremos evitar o problema de colisão de nomes.
Ocorre colisão de nomes quando importamos um módulo no qual existe uma função que, para azar nosso, tem o mesmo nome de uma função já importada. Isto não é tão improvável assim, programadores tem tendência de usar certos tipos de nome com frequência e colisões não são impossiveis. Havendo colisão pode ocorrer um êrro (exceção) ou pode ocorrer superposição das funções de modo que só a última importada permanece visível.
Enfim, eis a sintaxe desta outra forma de importar funções: From modulo import nome_função

O módulo shutil contém funções muito úteis para manipular arquivos e diretórios (copiar, mover, etc). Digamos que queremos copiar um diretório inteiro, com todos seus arquivos e seus subdiretórios para um novo caminho. A função que faz isto pode ser importada de shutil assim:
In [7]:
from shutil import copytree

# agora use a função copytree.....

erros

Erros são inevitáveis. Obviamente erros básicos em programas podem ser eliminados ou reduzidos atráves de analise dos algorítmos e bastante testes, mas há erros muito difíceis de eliminar que são gerados fora dos programas.
  1. Por exemplo, um script correto vai baixar uma página de uma url mas o site remoto não responde. Ou a comunicação interrompe subitamente no meio do processo. Ou a página foi removida do site mas o usuário do script não sabe disso.
  2. Um arquivo é lido mas seu conteúdo contém caracteres não-interpretáveis na codificação corrente da nossa máquina. O leitor de arquivos não sabe o que fazer com aquilo e gera uma exceção (um êrro) para nos avisar do ocorrido.
E assim por diante. Normalmente os programas são feitos para gerar (lançat) uma exceção quando detetam uma situação assim. A exceção ou exception é um objeto gerado pelo programa que detetou anormalidade e o usuário pode interrogar tal objeto para saber o que houve e o que fazer a respeito.
Como a maioria das linguagens procedurais modernas o Python possue um jeito de capturar exceções (exception) para permitir gerenciar o desastre. É o comando try - except cuja sintaxe é assim:
try: bloco de comandos onde pode surgir uma exceção except tipo de exceção a capturar: bloco de comandos para tratar a exceção
O primeiro bloco de comandos, sob o try, é onde o programador prevê que pode ser gerada uma ou mais exceções. O comando seguinte do par, o except, nomeia o tipo do objeto exceção que deve ser capturado, se ocorrer, e é seguido por outro bloco de comandos (tipicamente um print() detalhando o erro para um usuário do programa) para tratar a exceção.
In [11]:
# tenta baixar página html de uma url dada
import requests
try:
    res = requests.get('http://google.com')        
except requests.exceptions.HTTPError as e:     # captura exceções tipo HTTPError geradas pelo pacote requests
    print(e)           # imprime mensagem de erro
    
In [12]:
# le um numero do teclado mas usuário pode digitar letras, etc
try:
    print('digite um número')
    n = int(input())
    print(n)
except ValueError:
    print('caracter inválido foi digitado')
digite um número
12k
caracter inválido foi digitado
No ultimo exemplo a exceção era um objeto tipo ValueError, gerado pela função int(). Em geral como saber quais exceções devemos capturar?
Não há regra fixa, isto depende de quem programou a função e normalmente deveria ser descrito na documentação da mesma. Existe uma classe basica chamada Exception da qual são derivadas muitas exceções mas de modo geral procure saber o que capturar lendo a documentação das funções que usar.
Alguns tipos de exceções nativas do Python podem ser vistas na sua documentação oficial.
Outras exceções podem ser criadas pelo programador de determinada função e ele fica livre de faze-las do jeito que quiser. Para criar e lançar uma exceção o programador usa um comando raise mas isto não nos interessa no momento.
Mais detalhes sobre o comando raise podem ser vistos nos docs oficiais.

Leitura de arquivos

Para ler ou escrever em arquivos usaremos bastante a função open() nativa do Python. O que esta função faz é somente abrir um arquivo para poder manipular seu conteúdo. A leitura ou escrita são feitos por outros módulos.
Tendo lido ou escrito em um arquivo devemos sempre fechá-lo novamente pois arquivos mantidos abertos drenam recursos do sistema.
Vejamos um exemplo. Vamos criar um arquivo texto "vinicius.txt", escrever nele um conteúdo e fechá-lo.
In [1]:
texto = r'Não comerei da alface a verde pétala  \
Nem da cenoura as hóstias desbotadas  \
Deixarei as pastagens às manadas  \
E a quem maior aprouver fazer dieta.'

name = 'vinicius.txt'
file = open(name, 'w')         # abrir arquivo para escrita 'w'
file.write(texto)
file.close()
Agora vamos ler o arquivo e verificar seu conteúdo
In [2]:
file = open(name, 'r')
s = file.read()
file.close()
s
Out[2]:
'Não comerei da alface a verde pétala  Nem da cenoura as hóstias desbotadas  Deixarei as pastagens às manadas  E a quem maior aprouver fazer dieta.'
Uma outra forma de manipular arquivos é com o comando with. Não é necessário fechar o arquivo, o comando with faz isto.
In [4]:
with open(name, 'r') as f:
    txt = f.read()

txt   
Out[4]:
'Não comerei da alface a verde pétala  Nem da cenoura as hóstias desbotadas  Deixarei as pastagens às manadas  E a quem maior aprouver fazer dieta.'

No comments:

Post a Comment