ProgramadoresCaprendendoPython

Python para programadores C e/ou C++

Introdução

Algumas pessoas provavalmente vão querer me bater por estar fazendo isto. Há algum tempo atrás, antes de fazer este tutorial eu provavelmente estaria entre essas pessoas. Programadores que seguirem apenas este tutorial e não se dedicarem a realmente aprender uma linguagem nova, que geralmente incentiva formas de pensar diferente que as que o programador já sabia, provavelmente irão produzir programas feios e nada "pythonicos".

Por que escrever um documento que pode originar programas ilegiveis, ou pelo menos "não-pythonicos"? Recentemente eu tive a experiência de trabalhar em um projeto feito em Python com vários programadores que não sabiam programar em Python. O tempo era curto e eles já sabiam C. Em uma tentativa desesperada de não ter que fazer o trabalho todo sozinho, fiz este tutorial, que de fato ajudou. E para minha surpresa o código não ficou muito ruim, houveram alguns módulos um pouco problemáticos, mas que puderam ser consertados depois que o software já estava pronto e funcionando. Além dessa experiência, que pode acontecer a outras pessoas, eu também acho que quem já sabe C pode achar este tutorial útil para começar a aprender Python, afinal, existem várias ideias que são comuns a essas linguagens e este guia pode poupar uma leitura massante para descobrir como definir uma função em Python, por exemplo.

Exemplos

Condicional (if e switch)

if em C

if (y < x || z == w) {        
    /* codigo */              
} else if (x == y && z > w) { 
    /* mais codigo */         
else {                        
    /* mais mais codigo */    
}                             

if em Python

   1 if y < x or z == w:
   2     # codigo             
   3     pass
   4 elif x == y and z > w:
   5     # mais codigo
   6     pass
   7 else:
   8     # mais mais codigo
   9     pass

Note que python é sensível a endentação, assim, a palavra-chave pass se faz necessária quando não há nenhum comando. Nesse mesmo exemplo, se colocassemos código após os ifs não precisariamos colocar a palavra-chave pass. Por exemplo:

   1 if y < x or z == w:
   2     # codigo             
   3     x = 2
   4 elif x == y and z > w:
   5     # mais codigo
   6     y = 3
   7 else:
   8     # mais mais codigo
   9     z = 5

switch em C

switch (c) {
    case 'a':
    /* codigo */
    break;
    case 'b':
    /* codigo */
    break;
    default:
    /* codigo */
    break;

switch em Python

Python não possui o comando switch, a maneira mais comum de fazer um código similar é usando if-else.

   1 if c == 'a':
   2     # codigo
   3     pass
   4 elif c == 'b':
   5     # codigo
   6     pass
   7 else:
   8     # codigo
   9     pass

Loops (while e for)

for em C

for (i = 0; i < N; i++)  
    /* codigo */;
for (i = N; i > 0; i--)  
    /* codigo */;
for (i = 0; i < N; i+=2) 
    /* codigo */;

for em Python

   1 for i in xrange(N): 
   2     # codigo
   3     pass
   4 for i in xrange(N, 0, -1):
   5     # codigo
   6     pass
   7 for i in xrange(0, N, 2):
   8     # codigo
   9     pass

O for de python sempre usa um iterador e pode ser utilizado para iterar sobre uma lista, semelhante com o que acontece em C++.

for com iterador em C++

for (iter = lista.begin(); iter != lista.end(); iter++)
    T x = *iter; /* um elemento de uma lista de tipo T */

iterando em um array em C

int arr[] = {1, 2, 3}, i, x;
for (i = 0; i < 3; i++)
    x = arr[i]; /* elemento do array */

for com iteradores em Python

O uso de iteradores ocorre de forma natural em Python.

   1 for item in lista:
   2     x = item #elemento da lista

A variável item será um item da lista a cada iteração. Enquanto em C++ usaria-se *iter para pegar um elemento, em Python o elemento é a própria variável item.

while em C

while (x > y)
    /* codigo */;

while em Python

   1 while x > y:
   2     # codigo
   3     pass

Criando funções

em C

int foo(int *i, char *s)
{                       
    return *i;          
}                       

em Python

   1 def foo(i, s):
   2     return i

Criando classes

em C++

class Foo {     
    /* codigo */
}

em Python

   1 class Foo(object):
   2     # codigo

Não se preocupe com essa herança de object nas classes Python. Elas podem ser definidas apenas como class Foo: também, mas aí serão old-style class.

Herança de classe

em C++

virtual class A : B {
    /* codigo */

em Python

   1 class A(B):
   2     #codigo
   3     pass

Todas classes em python são virtuais.

Método privado

em C++

class A {               
    private:
    void foo() {
        /* codigo */    
    }                   
}                       

em Python

   1 class A(object):
   2     def __foo(self):
   3         # codigo
   4         pass

Construtor de Classes

em C++

class A {            
public:
    A() {     
        /* codigo */ 
    }                
}

em Python

   1 class A(object):
   2     def __init__(self):
   3         # codigo
   4         pass

Acessando atributos do objeto

em C++

class A {
    public:
    int x;                     
    void foo() {        
        x = 2;                 
        /* ou */               
        this.x = 2;            
    }                          
}

em Python

   1 class A(object):
   2     def __init__(self):
   3         self.x = 0
   4     def foo(self):
   5         self.x = 2

O self em Python é passado explicitamente e funciona como o this de C++. A sintaxe sem o this que C++ permite não existe em Python.

Um pouco de teoria

Em python só podemos mexer em referências, enquanto em C podemos escolher entre trabalhar com valor ou referência. Essas duas formas de acesso estão representadas no código:

int i = 30;                    
/* ou */                       
int *i = malloc(sizeof (int)); 
*i = 30;                       

Em Python só temos o equivalente ao segundo caso:

   1 i = 30  # é o mesmo que o código com ponteiros em C

Nesse caso i é uma referência para o número 30. Apesar disso não há aritimetica de ponteiros em Python. Ao fazermos

   1 j = 20
   2 x = i + j

O valor de x será 50. Enquanto em C isso seria soma de dois ponteiros, em python sempre utilizamos o valor que é apontado. O código acima é equivalente a

int *i = malloc(sizeof (int)); 
int *j = malloc(sizeof (int)); 
int *x =  malloc(sizeof (int)); 
*i = 30;                       
*j = 20;
*x = *i + *j;

Em Python as passagens para funções são por valor, mas só temos referencias. Então sempre passamos referências ao chamar uma função, apesar de que nem todo objeto é mutável em python. Assim, mesmo passando alguns objetos por referência não será possivel atualizar o valor dele.

Considere o seguinte exemplo feito no interpretador interativo de Python (execute o interpretador python sem parâmetros para iniciá-lo):

>>> def foo(x):
...    x += 5
>>> y = 10
>>> foo(y)
>>> y
10

y não é modificado, o que modificamos no código de foo foi uma referência que foi passada por valor para a função.

>>> def foo(x):
...    x.append(2)
>>> y = []
>>> foo(y)
>>> y
[2]

Como o ponteiro para a lista foi passado, ao alterarmos a lista com append, quem foi alterada foi a lista passada como um ponteiro por parâmetro. Não uma cópia dela.

Dicionários em python:

>>> x = {'a':123, (1, 2):'foo', 5 : [1, 2, 3]}
>>> x['a']
123
>>> x[(1, 2)]
'foo'
>>> x[5]
[1, 2, 3]

Qualquer objeto imutável pode servir como uma chave de dicionário em python e qualquer objeto pode servir como um valor.

Tuplas em Python

>>> ('af', 3)
('af', 3)

Para informações sobre os métodos dos tipos padrão digite help no interpretador python:

>>> help('list')
>>> help('dict')
>>> help('str')
>>> help('int')
>>> help('tuple')


Rafael C. Almeida (RafaelAlmeida)

ProgramadoresCaprendendoPython (editada pela última vez em 2008-09-26 14:07:17 por localhost)