Python

O que é Python?

  • Linguagem interpretada.
  • Dinamicamente tipada.

O Zen de Python

  • Bonito é melhor que feio.
  • Explícito é melhor que implícito.
  • Simples é melhor que complexo.
  • Complexo é melhor que complicado.
  • Plano é melhor que aninhado.
  • Esparço é melhor que denso.
  • Legibilidade conta.
  • Casos especiais não são especiais o suficiente para quebrar as regras.
  • Embora praticabilidade ganhe de puridade.
  • Erros nunca devem passam silenciosamente.
  • A não ser que sejam explicitamente silenciados.
  • Em caso de ambiguidade, evite a tentação de adivinhar.
  • Deve haver um -- e preferencialmente apenas um -- modo óbvio de fazer algo.
  • Embora talvez não seja tão óbvio de primeira a não ser que você seja Holandês.
  • Agora é melhor do que nunca.
  • Embora nunca seja melhor que agora mesmo.
  • Se a implementação é difícil de explicar, é uma péssima idéia.
  • Se a implementação é fácil de explicar, pode ser uma boa idéia.
  • Namespaces são uma grande idéia - vamos fazer mais desses!

O interpretador Python


Python 2.7.5 (default, Jun 25 2014, 10:19:55) 
[GCC 4.8.2 20131212 (Red Hat 4.8.2-7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
                        

Executando scripts Python:


python meuscript.py
                        

Tipos

Tipos Mutáveis e Tipos Imutáveis

Em Python, o tipo da variável pode ser mutável ou imutável, mas a definição é data pelo tipo e não pelo usuário.

Uma variável do tipo "imutável" não pode ser alterada depois de criada. Tentar modificar o conteúdo da variável vai criar uma nova instância.

Uma variável do tipo "mutável" é o contrário: tentar alterar vai alterar o objeto, não criar um novo.

A importância disto será visto mais pra frente, mas tenha isso em mente.

... ainda...

Existem tipos que são, na verdade, objetos e tem toda uma gama de funções para alterar/manipular/editar o conteúdo de uma variável.

Outros são tipos simples que não são objetos.

bool: Tipo booleano. Tipo simples.


>>> a = True
>>> b = False
                        

int: Um inteiro. Simples.


>>> a = 1
                        


>>> 1 + 1
2
                        

float: Um número com ponto flutuante. Simples.


>>> a = 1.1
>>> b = 1.0
                        

str: Strings. Objeto imutável.


>>> a = 'Python'
>>> b = "Python"
>>> c = """Python
>>> Rocks!"""
                        

unicode: Strings em Unicode. Objeto imutável.


>>> a = u'Python'
                        

list: Listas. Objeto mutável.


>>> a = [1, 2, 'Python', ['Outra lista']]
                        

dict: Um dicionário/objeto/mapa. Objeto mutável.


>>> a = {'Python': 'Rocks',
>>> 1: 1.0}
                        

tuple: Um conjunto de elementos. Objeto imutável.


>>> a = ('Python', 1)
>>> b = (2,)
                        

E ainda (mas menos importantes):

  • None
  • Long (a = 1L)
  • Lambdas ( a = lambda a: a + 2)

Estruturas de Controle

(... que é o nome bonito para coisas tipo if, for...)

Antes de mais nada...

Blocos

Em Python, uma identação define um bloco.

Não tem { / }, não tem end, nada. Só blocos.

if [condição]


>>> if a == 1:
>>>     b = 2
>>> c = 3
                        

while [condição]


>>> a = 1
>>> while True:
>>>     a += 1
>>>     if a > 10:
>>>         break
                        

for [iterável]


>>> soma = 0
>>> for valor em [345, 123, 123, 34]:
>>>     soma += valor
                        

The fuck "ITERÁVEL"?

Um objeto "iterável" é aquele que pode ter elementos acessados usando [ e ].

(Na verdade, o objeto tem que ter um generator; para acesar elementos diretamente, o objeto tem que implementar a função __getitem__.)

Tipos iteráveis:

  • Listas (a[2])
  • Tuplas (a[2])
  • Dicionários (a['Python'])
  • Strings/Unicodes (a[2])

Strings como iteráveis:


>>> for l in 'Python':
>>>     print l
                        

Dicionários como iteráveis:


>>> d =  {'Python': 'Rocks', 'Parrot': 'Dead', 'Favorite Color': 'Blue'}
>>> for key in d:
>>> 	print key, d[key]
						

Ou ainda:


>>> d =  {'Python': 'Rocks', 'Parrot': 'Dead', 'Favorite Color': 'Blue'}
>>> for (key, value) in d.iteritems():
>>>     print key, value
					    

Slices

Slice é uma "extensão" de indíces de acesso.

Com slices, é possível "cortar" iteráveis, retornando um novo iterável.


iterável[start:end:step]
                        

(end é exclusívo.)


>>> a = [1, 2, 3, 4]
>>> print a[1:2]
[2]
                        

Deixar um índice em branco indica que:

  • start = 0
  • end = len(iterável)
  • step = 1


>>> a = [1, 2, 3, 4]
>>> print a[:2]
[1, 2]
                        

Índices negativos começam do final do iterável.


>>> a = [1, 2, 3, 4]
>>> print a[1:-1]
[2, 3]
                        

Lembre-se que strings também são iteráveis.


>>> a = 'Python Rocks'
>>> print a[7:-1]
'Rock'
                        

Deixar os dois índices em branco cria uma cópia "flat".


>>> a = [1, 2, 3, 4]
>>> print a[:]
[1, 2, 3, 4]
                        

Para fazer uma cópia de uma lista com outros iteráveis internos, existe o módulo deepcopy.

Funções

def [nome_da_função]([parâmetro], [parâmetro], ...):


>>> def funcao(a, b, c):
>>>     return (a + b) / c
						

Classes

Ok, algumas coisas a serem vistas antes de entrar em classes:

Existem dois tipos de classes: old-style e new-style.

A diferença é que classes "new-style" sempre extendem da classe object, enquanto que "old-style" não extendem ninguém.

Por baixo dos panos, "new-style" e "old-style" funcionam de forma diferente, mas isso não é visível para o programador.

Para todos os casos e efeitos, "old-style" não deve mais ser usado.

No Python 3, não existem mais classes "old-style", mas a sintaxe removeu a necessidade de extender object.

(Ou seja, no Python 3 uma classe se parece com o "old-style" do Python 2.)

this/self não é uma variável implícita da classe: Ela tem que constar sempre na definiçào do método.

O construtor da classe é chamado __init__.

Não existe função para o destrutor.

Existem ainda outras funções (como o __getitem__ comentado anteriormente), mas não vamos falar sobre elas nesse momento.


>>> class MyClasse(object):
>>>     def __init__(self):
>>>         self.valor = 0
>>>     def show(self):
>>>         print self.valor
    				    

Para instanciar uma classe, basta chamar a classe como se fosse uma função.


>>> my = MyClasse()
>>> my.show()
0
				        

Se o construtor tiver parâmetros, estes devem ser passados durante a instanciação, como se a "função" classe tivesse parâmetros.


>>> class MyClasse(object):
>>>     def __init__(self, name):
>>>         self.name = name        
>>>     def show(self):
>>>         print self.name
        
>>> my = MyClasse('Julio')
>>> my.show()
Julio