{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Geradores\n", "\n", "Geradores são objetos que entregam uma seqüência de valores. Os valores podem estar armazenados em memória ou serem gerados quando solicitados.\n", "\n", "Um gerador frequentemente utilizado é o `range`. Na saída abaixo, note como não é mostrada a seqüência de valores. Isso é porque esse objeto gera os valores quando eles forem necessários." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "range(19)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Uma forma de usar os valores é percorrê-los em um `for`:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "8\n", "27\n", "64\n", "125\n", "216\n", "343\n", "512\n" ] } ], "source": [ "for i in range(9):\n", " print(i**3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Para cada iteração do `for`, um novo valor é solicitado ao objeto gerador `range(0,9)`.\n", "\n", "A função `map`, que aplica uma função fornecida a todos os valores passados, também retorna um objeto gerador. Isto é, a função será aplicada aos valores na medida do necessário." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "map(lambda x: 2*x - 3, [1, 4, 7, 9])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Não acredita? Então veja as temporizações abaixo:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The slowest run took 10.39 times longer than the fastest. This could mean that an intermediate result is being cached.\n", "1000000 loops, best of 3: 1.14 µs per loop\n" ] } ], "source": [ "%timeit map(lambda x: x**2, range(10))" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The slowest run took 9.35 times longer than the fastest. This could mean that an intermediate result is being cached.\n", "1000000 loops, best of 3: 1.21 µs per loop\n" ] } ], "source": [ "%timeit map(lambda x: x**2, range(1000))" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The slowest run took 10.04 times longer than the fastest. This could mean that an intermediate result is being cached.\n", "1000000 loops, best of 3: 1.2 µs per loop\n" ] } ], "source": [ "%timeit map(lambda x: x**2, range(10000000))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Se queremos ver todos os valores gerados, podemos converter o gerador para uma lista." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[0, 1, 2, 3, 4, 5, 6, 7, 8]" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(range(9))" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[-1, 5, 11, 15]" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(map(lambda x: 2*x - 3, [1, 4, 7, 9]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Outra função que retorna um gerador é a função `filter`." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "filter(lambda x: x ** 2 < 100, range(20))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Tipos de geradores\n", "\n", "Há dois tipos de geradores:\n", "\n", "1. Expressões geradoras\n", "1. Funções geradoras" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Expressões geradoras\n", "\n", "Expressões geradoras são criadas substituindo os `[]` de uma *list comprehension* por `()`.\n", "\n", "Abaixo temos uma *list comprehension*, que retorna uma lista com todos os valores:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[i ** 2 for i in range(10)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Podemos criar uma expressão geradora com os mesmo valores usando `()`:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [], "source": [ "valores = (i ** 2 for i in range(10))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Agora, `valores` é um objeto gerador, que pode, por exemplo, ser usado num `for`:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "4\n", "9\n", "16\n", "25\n", "36\n", "49\n", "64\n", "81\n" ] } ], "source": [ "for x in valores:\n", " print(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Os parêntesis da expressão geradora podem ser omitidos em locais onde a sintaxe do Python já exige parêntesis, por exemplo, na passagem de parâmetros para funções ou métodos:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'A B C X Y Z'" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "' '.join(v.strip().upper() for v in 'a , b ,c, x, y,z'.split(','))" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "285" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sum(x * x for x in range(10))" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[2, 4, 6, 8]" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(x*2 for x in (abs(x) for x in [-1,-2,3,-4]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Funções geradoras\n", "\n", "Funções geradoras são funções que criam um objeto gerador. Podemos conseguir uma função geradora usando `yield` ao invés de `return`. Neste caso, o valor fornecido no `yield` será retornado, mas a função continuará ativa (não termina ainda). Quando for solicitado um novo valor, a função voltará a executar continuando da instrução seguinte ao `yield`.\n", "\n", "Por exemplo, a função geradora abaixo gera os `n` primeiros número pares a partir de `0`:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def gerapares(n):\n", " corrente = 0\n", " for i in range(n):\n", " print('Vou retornar', corrente)\n", " yield corrente\n", " corrente += 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Quando a execução chega em `yield corrente` o valor atual da variável corrente é retornado como o próximo número gerado, e a execução da função é suspensa. Quando o código que usa o gerador solicitar o próximo valor, a execução retorna no comando seguinte (`corrente += 2`), como se não tivesse sido interrompida.\n", "\n", "A função pára de gerar novos números quando termina (por chegar ao fim do código ou por executar um `return`)." ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gerapares(10)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Vou retornar 0\n", "Valor atual: 0\n", "Vou retornar 2\n", "Valor atual: 2\n", "Vou retornar 4\n", "Valor atual: 4\n", "Vou retornar 6\n", "Valor atual: 6\n", "Vou retornar 8\n", "Valor atual: 8\n", "Vou retornar 10\n", "Valor atual: 10\n", "Vou retornar 12\n", "Valor atual: 12\n", "Vou retornar 14\n", "Valor atual: 14\n", "Vou retornar 16\n", "Valor atual: 16\n", "Vou retornar 18\n", "Valor atual: 18\n" ] } ], "source": [ "for x in gerapares(10):\n", " print('Valor atual:', x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A função pode ter o número de comandos `yield` que forem necessários. A execução é interrompida num `yield`, retorna no comando seguinte e continua até encontrar o próximo `yield`.\n", "\n", "Por exemplo, o gerador abaixo retorna alternadamente `'feliz'` e `'triste'`." ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def bipolar(n):\n", " for i in range(0,n,2):\n", " yield 'feliz'\n", " yield 'triste'" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Estou feliz\n", "Estou triste\n", "Estou feliz\n", "Estou triste\n", "Estou feliz\n", "Estou triste\n", "Estou feliz\n", "Estou triste\n", "Estou feliz\n", "Estou triste\n" ] } ], "source": [ "for estado in bipolar(10):\n", " print('Estou', estado)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vejamos agora uma comparação de desempenho de geradores listas. Primeiro, duas funções idênticas, uma retornando uma lista de valores e outra sendo um gerador para a mesma sequência de valores." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def cria_lista(n):\n", " corrente = 0\n", " res = []\n", " for i in range(1,n):\n", " corrente += i*i\n", " res.append(corrente)\n", " return res" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def gera_valores(n):\n", " corrente = 0\n", " for i in range(1,n):\n", " corrente += i*i\n", " yield corrente" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vemos que as duas geram os mesmo valores, mas de forma diferente:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[1, 5, 14, 30, 55, 91, 140, 204, 285]" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cria_lista(10)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[1, 5, 14, 30, 55, 91, 140, 204, 285]" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(gera_valores(10))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Agora vamos temporizar uma operação sobre esses valores (soma) de duas formas:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 loop, best of 3: 481 ms per loop\n" ] } ], "source": [ "%timeit sum(cria_lista(1000000))" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 loop, best of 3: 347 ms per loop\n" ] } ], "source": [ "%timeit sum(gera_valores(1000000))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vemos que neste caso o uso de geradores é mais eficiente.\n", "\n", "Por fim, vejamos uma função geradora para os `n` primeiros números da sequência de Fibonacci começada em 1, 1. (Implementação diferente da apresentada em aula.)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def fib(n):\n", " a, b = 1, 1\n", " for i in range(n):\n", " yield a\n", " a, b = b, a + b" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(fib(10))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exaustão de geradores" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ao usar geradores é importante lembrar que um gerador irá fornecer valores até terminar. Após fornecido o último valor, ele não fornecerá mais valores.\n", "\n", "Veja por exemplo o código abaixo." ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Primeira fase\n", "Estou feliz\n", "Estou triste\n", "Estou feliz\n", "Estou triste\n", "Segunda fase\n", "Terminado\n" ] } ], "source": [ "bipolar4 = bipolar(4) # Cria um objeto gerador e guarda referência\n", "print('Primeira fase')\n", "for estado in bipolar4:\n", " print('Estou', estado)\n", "print('Segunda fase')\n", "for estado in bipolar4:\n", " print('Estou', estado)\n", "print('Terminado')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Isso acontece com todos os geradores. Por exemplo, o `map`." ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Primeira vez\n", "0\n", "1\n", "8\n", "27\n", "64\n", "Segunda vez\n", "Acabou\n" ] } ], "source": [ "cubs = map(lambda x: x**3, range(5))\n", "print('Primeira vez')\n", "for q in cubs:\n", " print(q)\n", "print('Segunda vez')\n", "for q in cubs:\n", " print(q)\n", "print('Acabou')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Módulos\n", "\n", "Módulos são as unidades de organização de código em Python. Cada módulo corresponde, em geral, a um arquivo. Identificadores definidos em um arquivo fazem parte do escopo do módulo.\n", "\n", "Por exemplo, no arquivo `quadratura.py` temos a definição de duas funções de integração numérica (quadratura) pelo método dos trapézios. Para usar essas funções, devemos importar o módulo associado a esse arquivo e acessar as funções dentro do escopo do módulo." ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import quadratura\n", "import math" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "0.9999999999880265" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "quadratura.trapezoide_precisao(math.sin, 0, math.pi/2, 1e-10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "No arquivo `teste.py` definimos uma função `f` e uma variável `x`. O arquivo também executa um `print`. Note como ao importar o arquivo, o `print` é executado." ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Estou executando o modulo teste\n" ] } ], "source": [ "import teste" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Agora os identificadores do módulo são acessíveis. A função pode ser chamada, a variável pode ter seu valor lido ou alterado." ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Em f() do modulo teste\n" ] } ], "source": [ "teste.f()" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "teste.x" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "collapsed": true }, "outputs": [], "source": [ "teste.x = 2" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "teste.x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Os módulos são importados apenas uma vez. **Um `import` em módulo já importado não terá nenhum efeito**, mesmo que o código do módulo tenha sido alterado." ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import teste" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "teste.x" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import teste" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Se queremos forçar um módulo a ser recarregado (importante se fizemos alterações no código e queremos testá-las), devemos usar a função `reload` do módulo `imp`:" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from imp import reload" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Estou executando o modulo teste\n" ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "reload(teste)" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "teste.x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Outra possibilidade é importar identificadores individuais do módulo. No código abaixo, importamos apenas o identificador `x` do módulo `teste`." ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from teste import x" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Como já havíamos importado o módulo, agora temos dois `x`**: um no escopo do módulo e outro no escopo corrente. Essas são variáveis independentes (**a do escopo corrente é apenas inicializada com o mesmo objeto da variável do módulo**). Se mudarmos o objeto referenciado por uma das variáveis, a outra variável não é afetada." ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "teste.x" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x = 2" ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "teste.x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Em alguns casos é útil importar um módulo, mas com outro nome. Por exemplo, o código abaixo importa o módulo `teste`, mas para ser referenciado como `t`." ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import teste as t" ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t.x" ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Em f() do modulo teste\n" ] } ], "source": [ "t.f()" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(4, 4)" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "teste.x, t.x" ] }, { "cell_type": "code", "execution_count": 56, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(3, 3)" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t.x = 3\n", "teste.x, t.x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Além de importar identificadores individuais de um módulo para o escopo corrente, podemos importar todos os identificadores do módulo, usando um `*` no `from`:" ] }, { "cell_type": "code", "execution_count": 57, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from teste import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Agora tanto `f` como `x` fazem parte do escopo corrente." ] }, { "cell_type": "code", "execution_count": 58, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x" ] }, { "cell_type": "code", "execution_count": 59, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Em f() do modulo teste\n" ] } ], "source": [ "f()" ] }, { "cell_type": "code", "execution_count": 60, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x = 1" ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "teste.x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Podemos saber todos os identificadores definidos em um escopo usando a função `dir`. Abaixo seguem os identificadores no escopo do módulo (já importado) `teste`. (Os identificadores com `__` são pré-definidos pelo Python.)" ] }, { "cell_type": "code", "execution_count": 63, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['__builtins__',\n", " '__cached__',\n", " '__doc__',\n", " '__file__',\n", " '__loader__',\n", " '__name__',\n", " '__package__',\n", " '__spec__',\n", " 'f',\n", " 'x']" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dir(teste)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Isso pode ser útil quando queremos saber o que o módulo fornece, sem consultar a documentação." ] }, { "cell_type": "code", "execution_count": 64, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['__doc__',\n", " '__file__',\n", " '__loader__',\n", " '__name__',\n", " '__package__',\n", " '__spec__',\n", " 'acos',\n", " 'acosh',\n", " 'asin',\n", " 'asinh',\n", " 'atan',\n", " 'atan2',\n", " 'atanh',\n", " 'ceil',\n", " 'copysign',\n", " 'cos',\n", " 'cosh',\n", " 'degrees',\n", " 'e',\n", " 'erf',\n", " 'erfc',\n", " 'exp',\n", " 'expm1',\n", " 'fabs',\n", " 'factorial',\n", " 'floor',\n", " 'fmod',\n", " 'frexp',\n", " 'fsum',\n", " 'gamma',\n", " 'gcd',\n", " 'hypot',\n", " 'inf',\n", " 'isclose',\n", " 'isfinite',\n", " 'isinf',\n", " 'isnan',\n", " 'ldexp',\n", " 'lgamma',\n", " 'log',\n", " 'log10',\n", " 'log1p',\n", " 'log2',\n", " 'modf',\n", " 'nan',\n", " 'pi',\n", " 'pow',\n", " 'radians',\n", " 'sin',\n", " 'sinh',\n", " 'sqrt',\n", " 'tan',\n", " 'tanh',\n", " 'trunc']" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dir(math)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Diretórios como módulos\n", "\n", "Outra forma de definir módulos é através de diretórios. **Um diretório será correspondente a um módulo se ele possuir um arquivo denominado `__init__.py`**. Esse arquivo será executado quando o módulo for importado. Por exemplo o diretório `dirmod` pode ser importado como um módulo (veja código que acompanha este notebook, e analise o código dos arquivos incluidos para entender os resultados abaixo)." ] }, { "cell_type": "code", "execution_count": 65, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Importando o modulo dirmod\n" ] } ], "source": [ "import dirmod" ] }, { "cell_type": "code", "execution_count": 66, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "f do dirmod em primeiro\n" ] } ], "source": [ "dirmod.primeiro.f()" ] }, { "cell_type": "code", "execution_count": 67, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['__builtins__',\n", " '__cached__',\n", " '__doc__',\n", " '__file__',\n", " '__loader__',\n", " '__name__',\n", " '__package__',\n", " '__path__',\n", " '__spec__',\n", " 'dirmod',\n", " 'primeiro',\n", " 'segundo']" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dir(dirmod)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Outros arquivos dentro do diretório podem funcionar como \"submódulos\" do diretório:" ] }, { "cell_type": "code", "execution_count": 68, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import dirmod.primeiro\n", "import dirmod.segundo" ] }, { "cell_type": "code", "execution_count": 69, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "f do dirmod em primeiro\n" ] } ], "source": [ "dirmod.primeiro.f()" ] }, { "cell_type": "code", "execution_count": 70, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "g de dirmod em segundo\n" ] } ], "source": [ "dirmod.segundo.g()" ] }, { "cell_type": "code", "execution_count": 71, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from dirmod import *" ] }, { "cell_type": "code", "execution_count": 72, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "primeiro" ] }, { "cell_type": "code", "execution_count": 73, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "g de dirmod em segundo\n" ] } ], "source": [ "segundo.g()" ] } ], "metadata": { "kernelspec": { "display_name": "Python [default]", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.2" } }, "nbformat": 4, "nbformat_minor": 0 }