Rapidinhas sobre Python

A Sun criou um espaço dedicado ao Python dentro do Sun Developer Network.  Na página, existem links para o Dive Into Python, dicas para montar um ambiente com Django, Jython ou Python, GlassFish, etc. Vale ressaltar também que o NetBeans começou a dar suporte oficial para o Python.

A Apple começou a dar suporte para Python há algun tempo atras, permitindo que desenvolvedores criassem programas em  Python com interfaces gráficas nativas em Cocoa usando o Interface Builder e o XCode.

A impressão que eu tenho é que nos ultimos 12 meses, Python tem consistentemente ganhado espaço em blogs, sites especializados, projetos web. O futuro parece promissor.

Coisas bizarras de Python

Venho trabalhado nos meus projetos pessoais com Python há um certo tempo e estou bem satisfeito. Esta linguagem tem sido um fator importantíssimo na minha produtividade, e tem me permitido por minhas idéias no ar de forma estruturada e com qualidade em tempos recordes.

Mas acho importante identificar pontos falhos que possam ser melhorados. Ter uma visão crítica de uma linguagem não a desmerece e não me faz ser menos entusiasta. Foi assim com Java, é assim com Python.

Até agora, a única caracteristica de Python que realmente me incomodava era o fato de variáveis locais não terem escopo de bloco. Ou seja: uma variável criada dentro de um if existe após ele. Muitos consideram isso como um ponto que pode gerar vários erros bestas (e de fato pode), mas se bem utilizado, pode ser bem poderoso. Resumindo: requer cuidado, mas pode ser útil. Ninguém é perfeito…

Mas existem alguns limites…e hoje descobri uma característica que me incomoda. Não a ponto de eu deixar a linguagem, porque ainda acho que os benefícios dela são gigantescos. Mas incomoda. E fico feliz de ter descoberto isso antes de ter passado horas e horas quebrando a cabeça com comportamentos bizarros.

Chega de preâmbulos, vamos ao ponto:

def f(item, lista=[]):

     lista.append(item)

     print lista

Se executarmos a a função uma primeira vez, passando apenas um argumento, o resultado é o esperado: f(1) imprime [1] na tela. Mas se executarmos uma segunda vez, em vez de imprimir [2], a função f imprime [1,2]. Eu custei a acreditar nisso, e tive que confirmar pessoalmente.

Fazendo uma busca no Google, descobri na documentação oficial (http://docs.python.org/ref/function.html) que isto realmente é uma característica mapeada da linguagem:

Default parameter values are evaluated when the function definition is executed. This means that the expression is evaluated once, when the function is defined, and that that same “pre-computed” value is used for each call. This is especially important to understand when a default parameter is a mutable object, such as a list or a dictionary: if the function modifies the object (e.g. by appending an item to a list), the default value is in effect modified. This is generally not what was intended. A way around this is to use None as the default, and explicitly test for it in the body of the function […]

Ok, pelo menos está mapeado. Mas a frase texto acima merece “This is generally not what was intended. A way around this is to use None as the default, and explicitly test for it in the body of the function” merece destaque. Afinal, logo após a documentação descrever a funcionalidade, ela reconhece que o efeito é indesejado (afinal, parâmetro de função tem escopo local), e ainda por cima descreve a Solução Rápida de Eficiência Duvidosa, a famosa Gambiarra (ou workaround, no jargão técnico). Ou seja, o problema poderia ser resolvido na fonte e as funções de Python poderiam ter o mesmo comportamento das funções de outras linguagens.

Infelizmente, acabei de dar uma olhada na doc do futuro Python 3.0, e a feature permanece……

Conversando com o Twitter

Eu já divulguei aqui que o Job4Dev tem integração com o sistema de microblog Twitter, através do usuário job4dev, onde são enviadas as ofertas de emprego.

O que eu não divulguei ainda é que desde terça está no ar mais um projeto que contou com a minha participação: sigaseutime.com.br. A idéia é bem simples: utilizar o Twitter para agregar notícias e informações de jogos ao vivo do seu time de futebol favorito. Criamos contas para diversos times do Brasil e do mundo (sigaCorinthians, sigaPalmeiras, liveBarcelona, e por aí vai. Acesse o site para o obter a lista completa).

O que eu não contei também é que fazer integração via software com o Twitter é extremamente simples, graças à API REST de acesso. REST? REpresentational State Transfer, termo criado por Roy Fielding, computeiro americano e um dos principais autores da especificação do protocolo HTTP, em sua tese de PhD.

O próprio REST tem como pilar o protocolo HTTP. A idéia básica é definir que existem recursos (fontes de informação) que podem ser acessados através de um identificador global (que no caso do HTTP, é conhecido como URL), e que retornam uma representação da informação (XML, JSON, etc). Os recursos são considerados objetos, e o REST utiliza as ações do protocolo HTTP para agir sobre estes objetos: GET, POST (as mais famosas, para quem trabalha com sistemas web e com ajax), PUT e DELETE.

  • GET URI corresponde à operação de leitura de um objeto
  • POST URI correponde à operação de criação, atualização ou remoção de um objeto, utilizando dados enviados pelo comando.
  • DELETE URI corresponde à operação de remoção de um objeto.
  • PUT URI corresponde, assim como POST, à operação de atualização ou criação de um objeto.

Assim como no HTTP, o REST não armazena sessão: o acesso tem que ser feito sem que o recurso precise ter conhecimento de requisições passadas, proxys, caches e outros recursos utilizados em sistemas web. Ou seja: qualquer serviço REST pode ser acessado apenas com a URI apropriada e a ação desejada.

A API REST do Twitter permite acesso a todas as funcionalidades do sistema, de forma extremamente simples. Por exemplo: caso eu queira listar as mensagens recebidas pelo usuário job4dev em formato xml, basta acessar a URL http://twitter.com/statuses/friends_timeline/job4dev.xml. O sistema retorna informações também em JSON (neste caso, bastaria mudar o xml do final por json).

A maioria dos comandos requer autenticação, que no caso do Twitter é feita usando o Basic Auth: a informação de usuário e senha é enviada em um header chamado Authorization, cujo conteúdo é uma string na forma Basic <dados em base 64>, onde <dados em base 64> é usuario:senha codificado em base64 (formato muito utilizado para transmissão de dados na web).

Vou colocar aqui um exemplo em Python para enviar uma mensagem nova para uma conta no Twitter. A função encodestring é responsável por converter para base64, e a função urlencode gera uma string no formato correto para colocar na requisição HTTP:

auth = encodestring('%s:%s' % (user, password))[:-1]
header["Authorization"] = 'Basic %s' % self.auth
encoded_post_data = urlencode({"status":status})
req = Request(TwitterSender.url, encoded_post_data, header)
url_data = urlopen(req)

O mais interessante desta API é que além de ser simples, ela é muito bem documentada: http://groups.google.com/group/twitter-development-talk/web/api-documentation

Beleza booleana

Até há muito pouco tempo atrás, expressões booleanas para mim eram apenas uma questão de verdadeiro ou falso, ifs, whiles e do..whiles. Nesta época, eu ria quando encontrava trechos de códigosdo estilo

boolean b = true; if (b == true){...}.

A vida era simples, linda e limitada.

Daí eu comecei a brincar seriamente com javascript e python, e descobri que existe muito mais coisas entre o céu e as funções booleanas do que poderia sonhar minha vã filosofia. Neste mundo novo, expressões booleanas podem ser muito mais do que apenas true ou false: elas podem ser formas extremamente elegantes e compactas para atribuição de valores.

Vamos por partes. Em Java, apenas variáveis do tipo booleanas ou expressões que retornem variáveis do tipo booleanas (maior que, menor que, igual a, contém, …) podem ser utilizadas em expressões booleanas. Uma construção do tipo if(1) não funciona.

Em linguagens de script, qualquer objeto pode ser avaliado como uma expressão booleana. Em Python por exemplo, a seguinte regra é aplicada: valores False (booleano), 0, “”, e None (valor nulo) são avaliados como falso; qualquer outro valor é avaliado como verdadeiro. A expressão (1 and 2) seria avaliada como true por exemplo.

Um outro ponto interessante em Python e Javascript é que expressões booleanas não retornam simplesmente True ou False: elas retornam o valor de um dos objetos da expressão. Uma expressão com AND retorna o último valor da expressão caso todos elementos sejam avaliados como verdadeiros, ou retorna o primeiro valor que fez com que toda a expressão fosse avaliada como falsa. Por exemplo: 1 and "miguel" and 2 retorna 2, porque todos os elementos da expressão são verdadeiros, e portanto a expressão toda é verdadeira. Já 1 and 0 and 2 retorna 0, uma vez que este é o primeiro elemento avaliado como false. E como todos sabemos, se um elemento é falso, a expressão toda é falsa.

No caso de uma expressão OR, ela retorna o primeiro elemento que for avaliado como verdadeiro, ou o último elemento da expressão caso todos os anteriores sejam avaliados como falsos. Por exemplo (1 or 2) retorna 1, e (0 or "") retorna “”.

Ótimo. Então como podemos usar isso para escrever expressões compactas, úteis e elegantes? Eis algumas sugestões:

  • Valor default para uma variável: OR pode ser usado para garantir que caso um parâmetro seja passado com valor nulo para uma função por exemplo, ele receba um valor default:
    var v = param || “default”
  • Expressões ternárias: o uso de OR e AND pode criar uma função ternária em linguagens que não possuem esta construção (Python por exempl0):
    var v = (condicao AND valor1) OR valor 2

Aproveito pra levantar um ponto: estilo compacto é algo bom ou ruim? Um argumento muito utilizado contra expressões compactas como as descritas acima é que prejudica a legibilidade. De fato, pode ser mais difícil de ler à primeira vista. Mas mesmo construções mais verborrágicas podem ser dificeis de serem lidas: tudo depende de quão treinado é o olho e o cérebro do leitor. Portanto, eu acho que é apenas uma questão de estar acostumado a ler código de qualidade.

Markdown no Job4Dev

Acabou de sair do forno!

O formulário de cadastro de novas vagas do Job4Dev agora aceita o uso de markdown para formatação de texto. Para quem não sabe, markdown é um padrão de codificação simples de texto para geração de HTML. É muito usado por wikis e afins.

Exemplos de marcação markdown:

  • *texto em itálico*
  • **texto em negrito**

O parser do texto e geração do HTML ficou a cargo da lib Python Markdown.

Usuário de Django?

Encontre os programadores usuários de Django ao redor do mundo. Quem sabe não tem um na rua de baixo?

http://djangopeople.net/

Especial de Natal Log4Dev: construindo um site de notícias usando Python - Parte 2

Vamos dar uma olhada nos nossos requisitos, e apresentar algumas questões de tecnologia:

  • O site tem que ser capaz de autenticar e identificar unicamente cada usuário que deseja cadastrar links.
  • Deve ser capaz de manter uma lista de quem foi o primeiro a enviar um link, além da data que o link foi enviado.
  • Deve ter um sistema que permita ao usuário indicar se gostou (aprovou) ou não gostou (rejeitou) um link enviado por qualquer pessoa que utilize o serviço.
  • Deve permitir que cada link enviado possua um fórum de discussão.
  • Deve permitir que uma pessoa possa iniciar um tópico de discussão, sem enviar um link. No caso, vamos fazer o seguinte: se o usuário preencher apenas os campos de título e comentário em um formulário de link, mas deixar o campo para a URL em branco, vamos criar um link para um item dentro do próprio site.
  • Deve permitir ao usuário enviar um lote de links a partir de uma fonte que ele já conheça. Isso vai servir para que o sistema, no futuro, tenha uma grande base de links prévios para aprender rapidamente.
  • Deve permitir que o usuário faça o seu voto (aprovado/rejeitado) sem sair da página que está. Para isso, vamos usar uma pitada de AJAX.

Tendo os requisitos delineados, podemos ver que vamos precisar dos sistemas comumente usados em aplicativos web: um banco de dados, um servidor web, um sistema para geração de páginas dinamicamente. Além disso, teremos que usar alguma biblioteca para importar links e parsear RSS.

A parte de programação já foi definida no título: vamos usar Python. É o que estou usando ultimamente para meus outros projetos, é uma linguagem elegante, divertida (sim, diversão conta), dinâmica, com bibliotecas fartas e bem documentadas como parte da biblioteca-padrão. Se nada disso serviu como argumento, diga para o seu chefe que você vai aprender Python pois ficou sabendo que o pessoal do Google usa, e tudo que eles usam tem que ser bom, não é mesmo?

Para o servidor de banco de dados: PostgreSQL. Maduro, estável, bastante documentação. Outros bancos de dados serviriam, mas escolhi PostgreSQL por pura comodidade. Se você quiser portar os scripts SQL que eu colocar aqui para seu banco de preferência, creio que não terá dificuldades.

Para a parte de AJAX, vamos favorecer a prata da casa: Juice Lib é uma biblioteca pequena, mas com funcionalidades bem pensadas para a parte de comunicação assíncrona com o servidor. Eu tenho enchido um pouco o saco do Miguel na questão de manipulação de DOM (a juice faz isso através de extensão de métodos sobre string, o que pode vir a te causar dor de cabeça se o seu código Javascript começar a crescer muito), mas o resultado geral é poderoso o suficiente para que possamos ter o esquema de apresentação da votação em pouquíssimas linhas de Javascript.

Resta falar sobre qual sistema vamos usar para formarmos uma “Aplicação Web” propriamente dita. Controle de sessão, classes controllers, formas para acessar o banco de dados, apresentação de páginas construídas dinamicamente, etc, etc, etc.

Eu já disse que odeio frameworks. O que eu quero é algo que pudesse funcionar como um único módulo ou biblioteca, que pudesse ser importado a partir de um shell Python e me oferecer as funcionalidades necessárias para um webapp.

O que vamos usar, então, é um sistema que seja o anti-framework: esse sistema, para mim, é o web.py

O que diferencia o web.py dos outros frameworks para aplicações web desenvolvidas em Python?

Simples: a filosofia.

Muita atividade ocorreu na comunidade de desenvolvedores Python, buscando uma resposta para o sucesso do Ruby On Rails. Começaram então a pensar em implementar um framework que pudesse ser tão “pragmático” e “rápido” quanto o Ruby On Rails.

E isso levou a uma febre de grupos desenvolvendo frameworks para Python. Sistemas que fazem mapeamento OR. Que abstraem sua camada de dados completamente. Que abstraem a camada de apresentação completamente. Que abstraem a camada de controle completamente. Que escrevem elogios na tela enquanto eles fazem tudo automaticamente para você.

O problema: abstrações excessivas falham. Cada um dos grupos dos grandes frameworks (Turbogears, Pylons, Django) tinha o seu próprio dialeto para o desenvolvimento de aplicações web, alguma coisa parecida com Python, mas não exatamente Python.

Faltava uma solução que se propusesse a alavancar os conhecimentos tradicionais que as pessoas acumulam ao trabalhar com sistemas web.

O web.py tem essa filosofia. Por exemplo: ao invés de se preocupar em implementar um módulo que faça mapeamento OR para você, o web.py te dá um módulo que serve para facilitar o acesso ao banco de dados, diretamente e de forma segura. Ao invés de expor objetos em Python para uma camada de apresentação, o web.py facilita o trabalho de construir uma resposta HTTP. Ao invés de impor uma disciplina de trabalho, ele oferece as funcionalidades básicas para que você use seu conhecimento acumulado com outros problemas que você teve que resolver.

(Justiça seja feita: o Django parece ter aprendido parte dessa lição. Muito dos esforços recentes do Django para que ele chegue na versão 1.0 está sendo feito no sentido de retirar o que é chamado de “código mágico”.)

Isso não quer dizer que o web.py é perfeito. Não é. A última versão lançada possui algumas coisas no design que você pode até estranhar, e vou falar deles. Espero para ver se a próxima versão irá corrigir mesmo esses problemas. De qualquer forma, por se tratar de uma biblioteca de recursos auxiliares - ao invés de um framework - a ginástica necessária para contornar esses problemas é muito menor.

Chega de escrivinhar. Amanhã, vamos ao código.

Especial de Natal Log4Dev: construindo um site de notícias usando Python - Parte 1

Introdução

Sem dúvida, esse ano foi um ano interessante para quem participou da WWW. Se em 2006 a revista Time escolhou “Você” como pessoa do ano, nesse ano houve uma consolidação da idéia da “Web Social”.

Estamos só no começo. Estamos só agora descobrindo que a internet, antes do que uma rede de computadores, é uma rede de pessoas. O futuro da internet vai aprender a juntar essas ligações e formas de interação social (o “Grafo Social”) para trazer serviços mais inteligentes e mais adequados a cada um de nós.

Nesse espiríto, e aproveitando o fim de ano - onde todo mundo acaba diminuindo o ritmo de trabalho mesmo - eu pensei em fazer um pequeno passo-a-passo de um “Site Social”, para aqueles que pensam em oferecer um desses serviços.

A idéia

Uma das coisas mais comuns que vimos por aí foi a proliferação de sites onde os usuários mandam as notícias, e a audiência escolhe os textos que são “dignos de capa”, através de “votos” nos links. O maior exemplo para esse tipo de site é o Digg, site com muitos usuários no mundo todo.

Ainda que sites como o Digg até possam trazer eventualmente alguns textos interessantes, já se percebeu que é muito difícil ter um site onde o público seja o único responsável pela determinação do conteúdo relevante. Não por achar que as pessoas não sejam capazes de se gerenciarem, mas pelo fato de ser muito difícil de obter textos e notícias que sejam simultaneamente interessantes e agradem a um grande público.

O Reddit apresentou uma evolução nesse passo. Ele possui um filtro que aprende, através do seu histórico de votação, a te indicar quais links podem ser mais interessante para você.

Mas ainda falta alguma coisa: mesmo o filtro do Reddit não é capaz de me trazer links mais específicos, adequados para os meus interesses. Talvez, se ele puder saber quais os meus gostos, hábitos, idiomas que eu falo, comunidades das quais participo e outras informações gerais, talvez o filtro possa ser mais inteligente e aprender ainda mais.

Bem, eu vou ficar devendo a parte do filtro, por enquanto. Só vou dizer que o nosso site será capaz, quando você acabar, de cadastrar usuários, ver os links enviados, entrar num fórum de discussão para cada link e manter um histórico de votação.

O que eu passei fazendo nos últimos dois dias está aqui. Ao longo dos próximos dias, vou colocar os detalhes e o processo para o desenvolvimento de tal sistema.

Ah, sim. Isso é muito mais um exercício do que algo pra ser considerado software de produção. Trate com carinho. O que mais você queria em dois dias de trabalho?

Python

Python

De XKCD

Dicas Python

Achei este artigo sobre o modo Python de ver a vida

http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html

Bem interessante!

Python em 10 minutos

Recebi hoje o link deste tutorial de Python, Learn Python in 10 minutes. Dei uma rápida olhada, e parece ser bem útil, um bom kick-off.

PS: Isso me lembra quando li um tutorial de Perl em 10 minutos para começar a escrever um etiquetador de palavras. Mas isto é outra história…

Dez dicas sobre Python para programadores Java

1. Python não suporta a instrução switch. A solução mais trivial para obter o mesmo comportamento seria usar if else encadeado. Mas a solução mais pythonica (se é que o termo existe) é usar dicionários para isso, aproveitando o fato que a implementação desta estrutura de dados é extremamente eficiente e que funções são first-class objects.

Exemplo:


def funcA()
def funcB():
switch = {1: funcA, 2:funcB}
switch[valor]()

2. Em Python, tudo é objeto, desde os tipos primitivos int, boolean até o arquivo onde o código é gravado (chamado de módulo), passando por funções.

3. A cultura Java diz que o acesso a atributos de um objeto deve ser feito por meio de métodos getters e setters. Portanto, quando um programador Java escreve em Python, a tendência é criar estes métodos. A cultura Python define que o acesso aos atributos se faz através da chamada direta ao atributo. Por exemplo, se tenho o objeto meuObjeto, que possui o atributo meuAtributo, então o acesso se faz via meuObjeto.meuAtributo. Este padrão pode parecer estranho à primeira vista, pois estaria quebrando alguns paradigmas de programação orientada a objeto permitindo acesso direto à variável. E se eu quiser fazer validações antes de definir o valor do atributo? Está tudo previsto! Python por trás dos panos chama os métodos _get_<atributo> e _set_<atributo>. O comportamento padrão é simplesmente obter ou gravar o valor do atributo. Mas caso o desenvolvedor deseje determinar um comportamento específico, basta sobreescrever o método.

4. Variáveis e métodos privados em Python são definidos com dois _ antes do nome. Porém, eles não estarão completamente inacessíveis de fora. Simplesmente, o nome dele será concatenado com o nome da classe (name mangling) para dificultar o acesso. A idéia geral por trás disso é que ao definir um método ou atributo como privado, o desenvolvedor sinaliza que o uso da variável diretamente pode causar efeitos indesejáveis. Aquele que o fizer estará fazendo por sua conta e risco!

5. Métodos estáticos em Java são no fundo uma forma de contornar o fato que a linguagem exige que todos os métodos tem que estar em uma classe. É um recurso muito utilizado para se criar coleções de funções utilitárias genéricas (como a classe Collections). Em Python, o equivalente pode ser feito por meio de funções definidas no módulo, fora de um objeto.

6. Python suporta programação orientada a objetos, procedimental e funcional! Use e abuse desta liberdade.

7. Dicionários são extremamente eficientes e muito simples se operar em Python. Se estiver pensando em criar uma classe apenas para transportar dados, pense duas vezes se usar um dicionário não é a melhor solução.

8. Existem duas formas de se criar atributos de uma instância de um objeto em Python: ou dentro do método _init_, utilizando self.minhavariável, ou em qualquer ponto do código após a criação. Em Python, os atributos e variáveis são criados no momento do primeiro uso. Por exemplo:

class MinhaClass:
pass

instancia = MinhaClass()
instancia.variavel=1

O código acima cria uma classe MinhaClasse, uma instância desta classe e adiciona um atributo variável. Atributos criados dentro do código da classe e fora do método _init_ são equivalentes a variáveis estáticas em Java.

9. Variáveis e atributos tem escopo de módulo, classe, método ou função, mas não tem escopo de bloco. Isso significa que uma variável criada dentro de um if continuará viva fora dele. Cuidado!

10. A questão de uso de indentação para delimitação de blocos pode parecer estranho à primeira vista. Mas não é. Basta usar um editor decente, como PyDev para Eclipse ou python-mode para Emacs. O efeito colateral é que o código fica naturalmente organizado e fácil de ler.

Turbogears

Recentemente comecei a brincar com Turbogears. É um framework para desenvolvimento de aplicações web em Python seguindo o famoso modelo MVC (Model View Controller). O pacote é baseado em um conjunto de bibliotecas para as diferentes funcionalidades: MochiKit para apresentação (com suporte para AJAX), CherryPy para controle e SQLObject para a parte de persistência. O interessante é que cada uma dessas bibliotecas é um projeto separado, com equipes de desenvolvimento, site, etc..

O Turbogears pode ser integrado com servidor Apache, mas oferece um servidor web caso se deseje rodar standalone.

Comecei a brincar com o Zope, mas achei o ambiente um tanto quanto complexo. O Turbogears é mais parecido com o modelo de desenvolvimento de aplicações Struts, com o qual eu tenho mais experiência.  A vantagem do Turbogears é que ele é bem menos complexo em termos de arquivos de configuração uma vez que as configurações são diretamente codificadas em Python.

GPS + Google Maps

O link a seguir mostra o site de um cara que desenvolveu um pequeno aplicativo em python de 40 linhas que recebe os dados de um GPS via porta serial e exibe as coordenadas no Google Maps. O código é bem simples.

http://regexp.bjoern.org/archives/000186.html 

Nota importante: este é o primeiro post do log4dev em seu novo endereço !

[Python] Primeiras impressões

Bom, lendo meus últimos artigos, dá pra perceber que ultimamente andei brincando com Python. Fazia algum tempo que queria aprender esta linguagem, mas sempre rolava aquela preguiça básica. Há 3 semanas atrás tomei coragem, e comecei a programar.

Os motivos que me fizeram ficar interessado foram vários. Ouvi pela primeira vez falar de Python quando trabalhava no projeto AURORA, no CenPRA. Na época, a definição que me deram era que Python era uma ótima linguagem para integração de sistemas: uma espécie de cola. Depois li vários artigos que elogiavam a linguagem pela limpeza sintática e pela facilidade e velocidade de desenvolvimento de código. Além do mais, eu frequentemente preciso escrever alguns scripts para execução de tarefas cotidianas: a solução adotadas por outros desenvolvedores que trabalham comigo é Perl, que apesar de ser altamente poderosa, eu tenho sérios bloqueios com a sintaxe. No final, acabava optando por Java que pra pequenas tarefas cotidianas não é a mais adequada em geral, apesar de ser minha linguagem preferida e na qual tenho maior fluência. O argumento derradeiro foi saber que o Google utiliza muito Python

O fato é que acabei começando a aprender, e devo dizer que gostei. A estratégia de aprendizagem foi simples: comecei programando algoritmos básicos de computação (merge sort, quicksort, selection sort, heap sort, lista ligada, fibonacci, fatorial), para exercitar comandos básicos da linguagem como recursão, chamada de funções, if-then-else, loops, declaracão de variáveis, manipulação de listas, dicionário, tuplas e outras estruturas de dados. Depois, comecei a usar Python para escrever scripts “real life”, ou seja, scripts que tinham alguma funcionalidade no meu dia a dia. Veio a calhar pois atualmente estou processando algumas dezenas de milhares de arquivos contendo dados genéticos, e preciso executar operações como leitura e escrita de arquivos, análise de textos utilizando expressões regulares e geração de relatórios simples.

Não sou expert na linguagem ainda. Longe disso. Apenas escrevi algumas centenas de linhas de código, e não utilizei todos os recursos disponíveis (como orientação a objeto), portanto as impressões que colocarei aqui são apenas preliminares…

De fato a linguagem é bem limpa sintaticamente, e bem fácil de escrever. A questão do uso de indentação para separação dos blocos, que é o motivo principal de reclamação das pessoas que não gostam de Python, não chega a ser um problema quando se tem um editor apropriado (no meu caso estou usando Emacs com Python Mode): o efeito colateral é que o código é naturalmente organizado e fácil de ler. A documentação, centralizada no site www.python.org, é bem feita, com tutoriais para vários níveis, referencias, livros e mini how-tos, além de listas de discussões bem ativas.

As listas, tuplas e dicionários (também conhecidos como hashes) são o grande forte da linguagem, que possui funções e recursos sintáticos muito poderosos para manipulação destas. Segundo artigos que li, a implementação de hash de Python é uma das mais eficientes que existe. As variáveis em Python são dinamicamente tipadas: não se declara tipo de uma variável, mas uma vez que se atribui um tipo de variável, não se pode atribuir outro tipo de objeto.

O processo de IO (leitura e escrita básica de dados em arquivo) é muito simples e eficiente, assim como a implementaçnao de regexp. O modo de uso deste último não é tão direto quanto Perl, e se assemelha muito ao modelo implementado por Java, com patterns e matchers. Não consegui encontrar nenhum artigo comparando a performance das duas linguagens nesse quesito, mas minha experiência atual mostra que não existe uma grande diferença de velocidade…algum dia verifico isso.

Um ponto que eu não gostei muito: o fato de que Python, ao contrário de Perl, Java, C, C++ e outras linguagens, não possui escopo de bloco para variáveis. Ou seja: variáveis declaradas dentro de um bloco for, if ou while são válidas e visíveis fora dele. O escopo de variáveis é função, módulo, objeto ou método. Também não gosto muito do fato de bastar atribuir um valor a uma variável que ela passa a existir: um modo strict semelhante ao Perl seria bem vindo.

Alguns pontos importantes restam a ser analisados e aprendidos, como orientação a objeto, reflection, organização de pacotes e uso de bibliotecas como processamento de XML, sockets, HTTP e acesso à base de dados. Isso fica para um próximo artigo.

Next Page »