Escolar Documentos
Profissional Documentos
Cultura Documentos
luciano@ramalho.org
@ramalhoorg
Paul Graham,
Pycon US 2012
Linguagem
“expressiva”
O que isso
significa
na prática?
Linguagem
COBOL
Java
Java
Python
Python tem sido uma parte
importante do Google desde
o início, e continua sendo à
medida que o sistema cresce
e evolui... estamos procurando
mais pessoas com habilidade
nesta linguagem.
Demo: lis.py
>>> repl()
lis.py> (* 7 3)
21
lis.py> (define resposta (* 6 7))
lis.py> resposta
42
lis.py> (define ! (lambda (n) (if (= n 0) 1 (* n (! (- n 1))))))
lis.py> (! 4)
24
lis.py> (! 5)
120
lis.py> (! 197)
10007840558408082122130389497134473659904776124145643156372043719
15587343235626799299914070366966935566947378481954772384977466613
67777918006944650646265409257583733981874437495228286501182991424
47739508657606635346735333579872783783532869428043930552260307311
88238628318646302096556423610922923784067025686796088553504768000
00000000000000000000000000000000000000000000
lis.py> !
<function <lambda> at 0x1004cbd70>
lis.py>
Sobre Python
• Linguagem dinâmica
• compilador é parte do ambiente de runtime
• Tudo são objetos
• Ex.: inteiros, funções, classes, exceções etc.
• Multi-plataforma
• Interpretador, APIs, bytecode, GUIs etc.
@ramalhoorg
Implementações
• CPython: a principal, escrita em C
• incluída na maioria das distros GNU Linux e no
Mac OS X; vários pacotes para Windows
• Jython: escrita em Java
• parte de IBM WebSphere e Oracle WebLogic
• IronPython: escrita em C#, .net CLR
• desenvolvida pela Microsoft
@ramalhoorg
Implementações (2)
• PyPy: Python em Python
• Implementação em
linguagem de alto-nível
facilitando a inovação
• Desempenho 5x
melhor que CPython
• Incompatível com as
extensões em C
@ramalhoorg
2.5
Python: evolução
2006-09…2011-05
2.6
3.1
2009-06 • 3.0, 2.5 e anteriores: fossilizadas
• 2.6 e 3.1: manutenção por 5 anos
2.7
2010-07
3.2
2011-02
3.3
• 2.7 e 3.2: versões atuais
• 2.7: versão final da série 2.x
2012-09
⋮ @ramalhoorg
Pythonista: app para iPad
@ramalhoorg
Pythonista
@ramalhoorg
Pythonista
@ramalhoorg
@ramalhoorg
Pythonista
@ramalhoorg
Pythonista
@ramalhoorg
Pythonista
@ramalhoorg
CPython 2.7: instaladores
• GNU Linux: pré-instalado em quase toda distro
• usar gerenciador de pacotes ou compilar (é fácil)
• Windows
• Python.org: instaladores MSI para 32 e 64 bits
• ActiveState ActivePython: 32 e 64 bits
• Mac OS: 32 bits (x86 e PPC), 64 bits (x86)
@ramalhoorg
pythontutor.com
pythontutor.com
Exemplo de doctest
# coding: utf-8
"""
Calcula a média de uma sequência de números
>>> media([10])
10.0
>>> media([10, 20])
15.0
>>> media([1, 2])
1.5
"""
def media(seq):
return float(sum(seq))/len(seq)
@ramalhoorg
Para executar doctests
• Pela linha de comando:
• $ python -m doctest meu_script.py
• Usando um test-runner (unittest, nose, etc.)
• No próprio script (self-test):
if __name__=='__main__':
import doctest
print doctest.testmod(optionflags=doctest.REPORT_ONLY_FIRST_FAILURE
|doctest.REPORT_NDIFF
|doctest.NORMALIZE_WHITESPACE)
@ramalhoorg
Consoles interativos
• python
• integrado em IDEs
• iPython
• online
• bpython
• http://shell.appspot.com/
• IDLE • http://pythonwebconsole.thomnichols.org/
• http://www.pythonanywhere.com/
@ramalhoorg
IDEs, algumas opções
• PyDev (Eclipse)
• PyCharm (JetBrains) $$$
• Komodo Edit
• Komodo IDE $$$
• TextMate $ - OSX
• SublimeText $
• WingIDE $$$
@ramalhoorg
Em vez de IDE:
The Unix environment
• Linux ou OSX ou qualquer Unix:
• Emacs: python-mode.el
• vi: http://www.vex.net/~x/python_and_vim.html
@ramalhoorg
Configure o editor para...
• Indentar com 4 caracteres de espaço ao usar a
tecla TAB ou comandos de indentação multi-linha
• Salvar tabs como 4 espaços, nunca como tabs
• Limpar brancos no final das linhas ao salvar
• Indentação inteligente: preservar indentação da
linha acima e indentar automaticamente após: if,
elif, else, for, while, try, except, finally, def, class, with
@ramalhoorg
Comparando: C e Python
#include <stdio.h>
class Argumentos {
public static void main(String[] args) {
for (int i=0; i < args.length; i++)
System.out.println(args[i]);
}
}
produzem listas
qualquer iterável
resultado: uma lista
>>> s = 'abracadabra'
>>> l = [ord(c) for c in s]
>>> [ord(c) for c in s]
[97, 98, 114, 97, 99, 97, 100, 97, 98, 114, 97]
>>> s = 'abracadabra'
>>> {c for c in s}
set(['a', 'r', 'b', 'c', 'd'])
>>> {c:ord(c) for c in s}
{'a': 97, 'r': 114, 'b': 98, 'c': 99, 'd': 100}
@ramalhoorg
Tipos iteráveis embutidos
• basestring • frozenset
• str • list
• unicode • set
• dict • tuple
• file • xrange
@ramalhoorg
Funções embutidas que
consomem iteráveis
• all • max
• any • min
• filter • reduce
• iter • sorted
• len • sum
• map • zip
@ramalhoorg
Iteração em C (exemplo 2)
#include <stdio.h>
def tic():
rel['text'] = strftime('%H:%M:%S')
Para instalar
def tac():
tic()
Tkinter no
rel.after(100, tac) Ubuntu Linux:
class Relogio(Tkinter.Label):
def __init__(self):
Tkinter.Label.__init__(self)
self.pack()
self['text'] = strftime('%H:%M:%S')
self['font'] = 'Helvetica 120 bold'
self.tictac()
def tictac(self):
agora = strftime('%H:%M:%S')
if agora != self['text']:
self['text'] = agora
self.after(100, self.tictac)
rel = Relogio()
rel.mainloop()
oopy/exemplos/relogio_oo.py @ramalhoorg
Uma pequena
parte da
hierarquia de
classes do
Tkinter
herança múltipla
mixin
he
ran
ça
mú
ltipl
a
Um pouco mais da hierarquia de classes do Tkinter
Hierarquia de classes dos objetos gráficos doTkinter
Tudo é um objeto
• Não existem “tipos primitivos” como em Java
• desde Python 2.2, dezembro de 2001
>>> 5 + 3
8
>>> 5 .__add__(3)
8
>>> type(5)
<type 'int'>
@ramalhoorg
Funções são objetos
>>> def fatorial(n):
... '''devolve n!'''
... return 1 if n < 2 else n * fatorial(n-1)
...
>>> fatorial(5)
120
>>> fat = fatorial
>>> fat
<function fatorial at 0x1004b5f50>
>>> fat(42)
1405006117752879898543142606244511569936384000000000L
>>> fatorial.__doc__
'devolve n!'
>>> fatorial.__name__
'fatorial'
>>> fatorial.__code__
<code object fatorial at 0x1004b84e0, file "<stdin>", line 1>
>>> fatorial.__code__.co_varnames
('n',) @ramalhoorg
Funções são objetos
>>> fatorial.__code__.co_code
'|\x00\x00d\x01\x00j\x00\x00o\x05\x00\x01d\x02\x00S\x01|\x00\x00t\x00\x00|
\x00\x00d\x02\x00\x18\x83\x01\x00\x14S'
>>> from dis import dis
>>> dis(fatorial.__code__.co_code)
0 LOAD_FAST 0 (0)
3 LOAD_CONST 1 (1)
6 COMPARE_OP 0 (<)
9 JUMP_IF_FALSE
12 POP_TOP
5 (to 17)
Bytecode da
13 LOAD_CONST
16 RETURN_VALUE
2 (2)
função
>> 17 POP_TOP
18 LOAD_FAST 0 (0)
fatorial
21 LOAD_GLOBAL 0 (0)
24 LOAD_FAST 0 (0)
27 LOAD_CONST 2 (2)
30 BINARY_SUBTRACT
31 CALL_FUNCTION 1
34 BINARY_MULTIPLY
35 RETURN_VALUE
>>> @ramalhoorg
Tipos
@ramalhoorg
Alguns tipos básicos
>>> i = 7 Python 2.7 >>> i = 7 Python 3.2
>>> type(i) >>> type(i)
<type 'int'> <class 'int'>
>>> j = 2**100 >>> j = 2**100
>>> type(j)
int e long >>> type(j)
<type 'long'> unificados no <class 'int'>
>>> f = 7. Python 3 >>> f = 7.
>>> type(f) >>> type(f)
<type 'float'> <class 'float'>
>>> s = 'abc' >>> s = 'abc'
>>> type(s) str >>> type(s)
<type 'str'> x <class 'str'> SyntaxError
>>> u = u'abc' unicode >>> u = u'abc'
ou
>>> type(u) x
<type 'unicode'> <class ‘s tr’>
bytes
>>> b = b'ABC' >>> b = b'ABC' (Python 3.3)
>>> type(b) >>> type(b)
<type 'str'> <class 'bytes'>
>>> b[0] >>> b[0]
'A' 65
@ramalhoorg
Tipos embutidos (built-in)
• Implementados em C, por eficiência
• Métodos inalteráveis (como “final”, em Java)
• Texto: str, unicode (Python 2 e Python 3)
• Números: int, long (Python 2), float, complex, bool
• Coleções: list, tuple, dict, set, frozenset, bytes
(Python 3)
@ramalhoorg
Tipagem forte
• O tipo de um objeto nunca muda, e não existem
“tipos variantes”
• Raramente Python faz conversão automática
>>> a = 10
>>> b = '9'
>>> a + b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> a + int(b)
19
>>> str(a) + b
'109'
>>> 77 * None
Traceback (most recent call last):
File "<stdin>", line 1, in <module> @ramalhoorg
TypeError: unsupported operand type(s) for *: 'int' and 'NoneType'
Tipagem dinâmica:
variáveis não têm tipo
>>> def dobro(x):
... return x * 2
...
>>> dobro(7)
14
>>> dobro(7.1)
14.2
>>> dobro('bom')
'bombom'
>>> dobro([10, 20, 30])
[10, 20, 30, 10, 20, 30]
>>> dobro(None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in dobro
TypeError: unsupported operand type(s) for *: 'NoneType' and 'int'
@ramalhoorg
Duck typing
• “Se voa como um pato, nada como um pato e
grasna como um pato, é um pato.”
• Tipagem dinâmica permite duck typing (tipagem
pato): estilo de programação que evita verificar os
tipos dos objetos, mas apenas seus métodos
• No exemplo anterior, a função dobro funciona
com qualquer objeto x que consiga fazer x * 2
• x implementa o método __mult__(n), para n
inteiro
@ramalhoorg
Exemplo: tômbola
• Sortear um a um
todos os itens de
uma coleção finita,
sem repetir
• A mesma lógica é
usada em sistemas
para gerenciar
banners online
@ramalhoorg
Interface da tômbola
• Carregar itens
• Misturar itens
• Sortear um item
• Indicar se há mais
itens
@ramalhoorg
Projeto da tômbola
• UML:
diagrama de classe
@ramalhoorg
TDD: Test Driven Design
• Metodologia de desenvolvimento iterativa na qual,
para cada funcionalidade nova, um teste é criado
antes do código a ser implementado
• Esta inversão ajuda o programador a desenvolver
com disciplina apenas uma funcionalidade de cada
vez, mantendo o foco no teste que precisa passar
• Cada iteração de teste/implementação deve ser
pequena e simples: “baby steps” (passinhos de
bebê)
@ramalhoorg
Doctests
• Um dos módulos para fazer testes automatizados
na biblioteca padrão de Python
• o outro módulo é o unittest, da família xUnit
• Doctests foram criados para testar exemplos
embutidos na documentação
• Exemplo de uso:
$ python -m doctest cao.rst
oopy/exemplos/cao.rst @ramalhoorg
Sobrecarga de
operadores
@ramalhoorg
Sobrecarga de operadores
• Python permite que as classes definidas pelo
usuário (você!) implementem métodos para os
operadores definidos na linguagem
• Não é possível redefinir a função dos operadores
nos tipos embutidos
• isso evita surpresas desagradáveis
• Nem é possível inventar novos operadores
• não podemos definir ~, <=>, /|\ etc. @ramalhoorg
Objetos invocáveis
• Você pode definir suas próprias funções...
• E também novas classes de objetos que se
comportam como funções: objetos invocáveis
• basta definir um método __call__ para
sobrecarregar o operador de invocação: ()
• o(x)
• Exemplo: tômbola invocável
@ramalhoorg
Tômbola invocável
• Já que o principal uso de uma instância de tômbola
é sortear, podemos criar um atalho:
em vez de t.sortear() >>> t = TombolaInvocavel()
apenas t() >>> t.carregar([1, 2, 3])
>>> t()
3
>>> t()
from tombola import Tombola 2
class TombolaInvocavel(Tombola):
'''Sorteia itens sem repetir;
a instância é invocável como uma função'''
def __call__(self):
return self.sortear() @ramalhoorg
Alguns operadores
existentes
• Aritméticos: + - * / ** //
• Bitwise: & ^ | << >>
• Acesso a atributos: a.b
• Invocação: f(x)
• Operações em coleções: c[a], len(c), a in c, iter(c)
• Lista completa em Python Reference: Data Model
http://docs.python.org/reference/datamodel.html
@ramalhoorg
Exemplo: vetor (2d)
y
• Campos: x, y
• Métodos:
• distancia
Vetor(4, 5)
Vetor(2, 4)
class Vetor(object):
def __repr__(self):
return 'Vetor(%s, %s)' % (self.x, self.y)
@ramalhoorg
Carta de
baralho
class Carta(object):
def __repr__(self):
return 'Carta(%r, %r)' % (self.valor, self.naipe)
def __str__(self):
return self.valor + ' de ' + self.naipe
@classmethod
def todas(cls):
return [cls(v, n) for n in cls.naipes
for v in cls.valores] @ramalhoorg
Carta de
>>> zape = Carta('4',
'paus')
>>> zape.valor
'4'
def __repr__(self):
return 'Carta(%r, %r)' % (self.valor, self.naipe)
def __str__(self):
return self.valor + ' de ' + self.naipe
@classmethod
def todas(cls):
return [cls(v, n) for n in cls.naipes
for v in cls.valores] @ramalhoorg
Baralho
polimórfico (demo)
from carta_ord import Carta
class Baralho(object):
def __init__(self):
self.cartas = Carta.todas()
def __len__(self):
return len(self.cartas)
class Baralho(object):
def __init__(self):
self.cartas = Carta.todas()
def __len__(self):
return len(self.cartas)