diff --git a/python.html b/python.html index 6a0572a..b24da0f 100644 --- a/python.html +++ b/python.html @@ -352,7 +352,7 @@ python meuscript.py >>> a = 'Python' >>> b = "Python" >>> c = """Python ->>> Rocks!""" +... Rocks!"""

@@ -377,7 +377,7 @@ python meuscript.py


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

@@ -411,7 +411,7 @@ set(['a']) @@ -434,7 +434,7 @@ set(['a'])


 >>> if a == 1:
->>>     b = 2
+...     b = 2
 >>> c = 3
                         

@@ -445,9 +445,9 @@ set(['a'])


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

@@ -514,7 +514,7 @@ True


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

@@ -545,7 +545,7 @@ True


 >>> for l in 'Python':
->>>     print l
+...     print l
                         

@@ -555,7 +555,7 @@ True


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

@@ -565,7 +565,7 @@ True


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

Forma considerada "correta" é a anterior.

@@ -595,7 +595,7 @@ iterável[start:end:step]


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

@@ -611,7 +611,7 @@ iterável[start:end:step]


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

@@ -621,7 +621,7 @@ iterável[start:end:step]


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

@@ -631,7 +631,7 @@ iterável[start:end:step]


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

@@ -640,7 +640,7 @@ iterável[start:end:step]

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


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

@@ -672,7 +672,7 @@ iterável[start:end:step]


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

@@ -681,7 +681,7 @@ iterável[start:end:step]


 >>> def funcao(a, b, c):
->>>     return (a + b) / c
+...     return (a + b) / c
 >>>
 >>> funcao(b=2, c=3, a=10)
 4
@@ -734,6 +734,8 @@ iterável[start:end:step]
 
                         

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

+

(Existe, mas ninguém usa.)

+

Existem ainda outras funções mágicas, mas não vamos falar sobre elas nesse momento.

@@ -741,10 +743,10 @@ iterável[start:end:step]


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

@@ -766,10 +768,10 @@ iterável[start:end:step]


 >>> class MyClasse(object):
->>>     def __init__(self, name):
->>>         self.name = name
->>>     def show(self):
->>>         print self.name
+...     def __init__(self, name):
+...         self.name = name
+...     def show(self):
+...         print self.name
 
 >>> my = MyClasse('Julio')
 >>> my.show()
@@ -777,17 +779,34 @@ Julio
                         

+
+

Propriedades podem ser injetadas a qualquer momento.

+ +

+>>> class A(object):
+...     def __init__(self):
+...         self.value = 10
+>>>
+>>> a = A()
+>>> a.name = 'Julio'
+                        
+ +

Inserção de propriedades pode ser + barrada com o uso da variável mágica + __slots__, mas raramente é usado.

+
+

Herança


 >>> class A(object):
->>>     def __init__(self):
->>>         self.value = 10
+...     def __init__(self):
+...         self.value = 10
 >>> class B(A):
->>>     def __init__(self):
->>>         super(B, self).__init__()
->>>         self.name = 'AAAA'
+...     def __init__(self):
+...         super(B, self).__init__()
+...         self.name = 'AAAA'
                         

@@ -796,14 +815,14 @@ Julio


 >>> class A(object):
->>>     def __init__(self):
->>>         self.value = 10
+...     def __init__(self):
+...         self.value = 10
 >>> class B(object):
->>>     def __init__(self):
->>>         self.name = 'AAAA'
+...     def __init__(self):
+...         self.name = 'AAAA'
 >>> class C(A, B):
->>>     def __init__(self):
->>>         super(C, self).__init__()
+...     def __init__(self):
+...         super(C, self).__init__()
                         

@@ -812,17 +831,124 @@ Julio
-

Propriedades podem ser injetadas a qualquer momento.

+

super() é mais usado para resolução + hierárquia com herança múltipla.

+
+

->>> class A(object):
->>>     def __init__(self):
->>>         self.value = 10
->>>
->>> a = A()
->>> a.name = 'Julio'
+>>> class Adao(object): pass
+>>> class Eva(object): pass
+>>> class AvoPaterno(Adao, Eva): pass
+>>> class AvohPaterna(Adao, Eva): pass
+>>> class AvoMaterno(Adao, Eva): pass
+>>> class AvohMaterna(Adao, Eva): pass
+>>> class Pai(AvoPaterno, AvohPaterna): pass
+>>> class Mae(AvoMaterno, AvohMaterna): pass
+>>> class Filho(Pai, Mae): pass
+                        
+ +

+>>> help(Filho)
+                        
+
+ +
+

+Help on class Filho in module __main__:
+
+class Filho(Pai, Mae)
+ |  Method resolution order:
+ |      Filho
+ |      Pai
+ |      AvoPaterno
+ |      AvohPaterna
+ |      Mae
+ |      AvoMaterno
+ |      AvohMaterna
+ |      Adao
+ |      Eva
+ |      __builtin__.object
+                        
+
+ +
+

A ordem de resolução pode ser usada para inserir + mocks sem o uso de mocks.

+ +

... embora só sirva para mockar + objetos "é um" e não "contém um".

+
+ +
+

+>>> class Robo(object):
+...    def pegar(self, ferramenta):
+...        print 'Pegando', ferramenta
+...    def pra_frente(self):
+...        print 'Movendo pra frente'
+...    def pra_tras(self):
+...        print 'Voltando'
+...    def largar(self):
+...        print 'Largando ferramenta'
+                        
+
+ +
+

+>>> class RoboDeLimpeza(Robo):
+...    def clean(self, repeticoes=10):
+...        super(Robo, self).pegar('vassoura')
+...        for _ in xrange(repeticoes):
+...            super(Robo, self).pra_frente()
+...            super(Robo, self).pra_tras()
+...        super(Robo, self).largar()
+                        
+
+ +
+

+>>> class MockRobo(Robo):
+...     def __init__(self):
+...         self.acoes = []
+...     def pegar(self, ferramenta):
+...         self.acoes.append('Pegar {}'.format(ferramenta))
+...     def pra_frente(self):
+...         self.acoes.append('frente')
+...     def pra_tras(self):
+...         self.acoes.append('tras')
+...     def largar(self):
+...         self.acoes.append('largar')
+                        
+
+ +
+

+>>> class MockRoboDeLimpeza(RoboDeLimpeza, MockRobo):
+...     pass
+                        
+
+ +
+

+Help on class MockRoboDeLimpeza in module __main__:
+
+class MockRoboDeLimpeza(RoboDeLimpeza, MockRobo)
+ |  Method resolution order:
+ |      MockRoboDeLimpeza
+ |      RoboDeLimpeza
+ |      MockRobo
+ |      Robo
+ |      __builtin__.object
                         
+ +
+

+ Mais informações no vídeo de Raymond Hettinger: + Super Considered super! +

+
@@ -867,9 +993,8 @@ Julio


 >>> def a(l=[]):
->>>     l.append(1)
->>>     print l
->>>
+...     l.append(1)
+...     print l
 >>> a()
 [1]
 >>> a()
@@ -882,10 +1007,9 @@ Julio
 
                         


 >>> def a(l=None):
->>>     if not l:
->>>         l = []
->>>     l.append(1)
->>>
+...     if not l:
+...         l = []
+...     l.append(1)
 >>> a()
 [1]
 >>> a()
@@ -906,8 +1030,7 @@ Julio
                     


 >>> def a(*args):
->>>     print args
->>>
+...     print args
 >>> a(1)
 [1]
 >>> a(1, 2, 3, 4, 5)
@@ -920,8 +1043,7 @@ Julio
                     


 >>> def a(**kwargs):
->>>     print kwargs
->>>
+...     print kwargs
 >>> a(a=1)
 {'a': 1}
 >>> a(value1=10, a=2)
@@ -934,9 +1056,8 @@ Julio
                     


 >>> def a(*args, **kwargs):
->>>     print args
->>>     print kwargs
->>>
+...     print args
+...     print kwargs
 >>> a(a=1)
 []
 {'a': 1}
@@ -949,17 +1070,72 @@ Julio
                     


 >>> def a(a, b, *args, name=None, **kwargs):
->>>     print 'a =', a
->>>     print 'b =', b
->>>     print 'args =', args
->>>     print 'name = ', name
->>>     print 'kwargs =', kwargs
+...     print 'a =', a
+...     print 'b =', b
+...     print 'args =', args
+...     print 'name = ', name
+...     print 'kwargs =', kwargs
                         

Saída de uma chamada desta função fica a cargo do leitor.

+
+
+

for tem else

+
+ +
+

+>>> for i in xrange(10):
+...     if i == 1:
+...         break
+... else:
+...     print 'Oh no'
+                        
+ +

WAT

+
+ +
+

for tem else

+ +

else é chamado se a execução do loop + chegar ao final.

+ +

+>>> for record in all_content:
+...     if record.name = search:
+...         found = record
+...         break
+... else:
+...     found = None
+                        
+
+
+ +
+
+

try tem else

+
+ +
+

+>>> try:
+...    func_that_raises_exception()
+... else:
+...     print 'Yay!'
+                        
+ +

else é chamado quando + exceções não ocorrerem.

+ +

finally + SEMPRE é chamado.

+
+
+

"Functions are First Class Citizens"

@@ -968,12 +1144,10 @@ Julio


 >>> def funcao(a, b, c):
->>>     return (a + b) / c
->>>
+...     return (a + b) / c
 >>> def check(a, b, c, condition, function):
->>>     if condition:
->>>         print function(a, b, c)
->>>
+...     if condition:
+...         print function(a, b, c)
 >>> check(1, 2, 3, True, funcao)
 1
 >>> check(1, 2, 3, False, funcao)
@@ -988,12 +1162,10 @@ Julio
 
                         


 >>> class A(object):
->>>     def __init__(self):
->>>         self.value = 10
->>>
->>> def show_name(self):
->>>     print 'Julio'
->>>
+...     def __init__(self):
+...         self.value = 10
+... def show_name(self):
+...     print 'Julio'
 >>> a = A()
 >>> a.show = show_name
 >>> a.show()
@@ -1017,7 +1189,7 @@ Julio
                     


 >>> def retrieve(connection):
->>>     # faz algo com a conexão para recuperar dados.
+...     # faz algo com a conexão para recuperar dados.
                         

Problema: antes de sair executando algo na conexão, tem que ser @@ -1030,15 +1202,15 @@ Julio


 >>> def retrieve(connection):
->>>     # faz algo com a conexão para recuperar dados.
->>>
+...     # faz algo com a conexão para recuperar dados.
+
 >>> def update(connection):
->>>     # atualiza algo usando a função
->>>
+...     # atualiza algo usando a função
+
 >>> def check(connection, call):
->>>     if not connection.is_connected:
->>>         connection.retry()
->>>     call(connection)
+...     if not connection.is_connected:
+...         connection.retry()
+...     call(connection)
                         

Novo problema: Todo lugar onde antes era chamado retrieve @@ -1052,18 +1224,17 @@ Julio


 >>> from functools import wrap
->>>
 >>> def check(func):
->>>     def check_conn(*args, **kwargs):
->>>         # acha a conexão em args ou kwargs
->>>         if not connection.is_connected:
->>>             connection.retry()
->>>         return func(*args, **kwargs)
->>>     return check_conn
->>>
+...     def check_conn(*args, **kwargs):
+...         # acha a conexão em args ou kwargs
+...         if not connection.is_connected:
+...             connection.retry()
+...         return func(*args, **kwargs)
+...     return check_conn
+
 >>> @check
 >>> def retrieve(connection):
->>>     # faz algo com a conexão para recuperar dados
+...     # faz algo com a conexão para recuperar dados
                         

Não precisa alterar nenhuma chamada de retrieve.

@@ -1078,22 +1249,22 @@ Julio

 >>> class CheckConn(object):
->>>    def __init__(self, func):
->>>        self.func = func
->>>
->>>     def __call__(self, *args, **kwargs):
->>>         if 'connection' in kwargs:
->>>             connection = kwargs['connection']
->>>         else:
->>>             connection = args[0]
->>>
->>>         if not connection.is_connected:
->>>             connection.retry()
->>>         self.func(*args, **kwargs)
+...    def __init__(self, func):
+...        self.func = func
+...
+...     def __call__(self, *args, **kwargs):
+...         if 'connection' in kwargs:
+...             connection = kwargs['connection']
+...         else:
+...             connection = args[0]
+...
+...         if not connection.is_connected:
+...             connection.retry()
+...         self.func(*args, **kwargs)
 
 >>> @CheckCon
 >>> def retrieve(connection):
->>>     # retrieve
+...     # retrieve
                         
@@ -1111,16 +1282,16 @@ Julio

 >>> class CheckConn(object):
->>>    def __init__(self, func):
->>>        self._func = func
->>>
->>>    @property
->>>    def func(self):
->>>        return self._func
->>>
->>>    @func.setter
->>>    def func(self, value):
->>>        self._func = func
+...    def __init__(self, func):
+...        self._func = func
+...
+...    @property
+...    def func(self):
+...        return self._func
+...
+...    @func.setter
+...    def func(self, value):
+...        self._func = func
                         
@@ -1129,112 +1300,112 @@ Julio

 >>> class CheckConn(object):
->>>    def __init__(self, func):
->>>        self._func = func
->>>
->>>    @staticmethod
->>>    def from_text(self, text):
->>>        return CheckConn(getattr(self, text))
+...    def __init__(self, func):
+...        self._func = func
+...
+...    @staticmethod
+...    def from_text(self, text):
+...        return CheckConn(getattr(self, text))
                         
-
-
-

Comprehensions e Generators

+
+
+

Comprehensions e Generators

-

Python permite criar listas processando listas sem - for com list - comprehensions.

+

Python permite criar listas processando listas sem + for com list + comprehensions.

-

+                        

 >>> a = [1, 2, 3]
 >>> [item * 2 for item in a]
 >>> [2, 4, 6]
-						
+
-

Pra quem gosta de coisas "funcionais", é o mesmo que - map.

+

Pra quem gosta de coisas "funcionais", é o mesmo que + map.

-

+                        

 >>> a = [1, 2, 3]
 >>> map(lamba f: f * 2, a)
 >>> [2, 4, 6]
-						
-
+
+
-
-

Comprehensions (contd.)

-

É possível filtrar elementos com list comprehensions.

+
+

Comprehensions (contd.)

+

É possível filtrar elementos com list comprehensions.

-

+                        

 >>> a = [1, 2, 3]
 >>> [item for item in a if item > 2]
 >>> [3]
-						
+
-

Funcionalmente, é o mesmo que filter.

+

Funcionalmente, é o mesmo que filter.

-

+                        

 >>> a = [1, 2, 3]
 >>> filter(lambda f: f > 2, a)
 >>> [3]
-						
-
+
+ -
-

Generators

+
+

Generators

-

Enquanto que comprehensions criam novas listas, generators - geram elementos sob demanda.

+

Enquanto que comprehensions criam novas listas, generators + geram elementos sob demanda.

-

+                        

 >>> a = [1, 2, 3]
 >>> (item * 2 for item in a)
 <generator object <genexpr> at 0x7f8673dfc050>
-						
-
+ +
-
-
Generators (contd.)
+
+
Generators (contd.)
-

+                        

 >>> [item for item in range(5000000)]
-						
+
-

vs

+

vs

-

+                        

 >>> (item for item in xrange(5000000))
-						
-
+ +
-
-
Generators (contd.)
+
+
Generators (contd.)
-

+                        

 >>> [item for item in range(5000000)][:5]
-						
+
-

vs

+

vs

-

+                        

 >>> (item for item in xrange(5000000))[:5]
-						
-
+ +
-
-
Generators (contd.)
+
+
Generators (contd.)
-

+                        

 >>> def gen(max_value):
->>> 	for value in xrange(max_value):
->>> 		yield value * 2
-						
+... for value in xrange(max_value): +... yield value * 2 +
-

Generator functions não podem ter return!

-
-
+

Generator functions não podem ter return!

+ +
@@ -1249,45 +1420,45 @@ Julio

Context Managers

-

+                        

 >>> class Connection(object):
->>>    def __init__(self):
->>>        self._conn = None
->>>
->>>    def __enter__(self):
->>>        self._conn = self._make_connection()
->>>        return self._conn
->>>
->>>    def __exit__(self, exc_type, exc_value, traceback):
->>>        self._conn.close()
->>>        if exc_type:    # then exc_value and traceback
->>>            print "Exception!", exc_type, exc_value
->>>            print traceback
-						
- -

+...    def __init__(self):
+...        self._conn = None
+...
+...    def __enter__(self):
+...        self._conn = self._make_connection()
+...        return self._conn
+...
+...    def __exit__(self, exc_type, exc_value, traceback):
+...        self._conn.close()
+...        if exc_type:    # then exc_value and traceback
+...            print "Exception!", exc_type, exc_value
+...            print traceback
+                        
+ +

 >>> with Connection() as connection:
->>>     connection.request('Value')
-						
+... connection.request('Value') +

Context Managers vs Exceptions

-

+                        

 >>> try:
->>>     conn = self._make_connection()
->>>     conn.request('value')
->>> finally:
->>>     conn.close()
->>> except Exception as exc:  # Bare exceptions are BAAAADDD!
->>>     print 'Exception!', exc
-						
+... conn = self._make_connection() +... conn.request('value') +... finally: +... conn.close() +... except Exception as exc: # Bare exceptions are BAAAADDD! +... print 'Exception!', exc +
-
+

Docstrings

@@ -1296,8 +1467,8 @@ Julio

 >>> def func(a):
->>>     """Função mágica"""
->>>     return a
+...     """Função mágica"""
+...     return a
 
 >>> print func.__doc__
 Função mágica
@@ -1388,7 +1559,7 @@ def send(sender, recipient, message_body, priority):
                             diretórios a serem pesquisados e um makefile com a opção
                             html para geração de arquivos HTML.)

-
+