Truques para Transição do Teu Código Python 2.7 para 3.7 ou Superior

Olá! Estás interessado em fazer a transição do teu código Python 2.7 para Python 3.7 ou superior? Então, vieste ao lugar certo. Ao longo deste artigo, vou mostrar-te diferentes truques que irão tornar esta tarefa, que parece assustadora, mais fácil para ti. Não te preocupes, vamos avançar passo a passo. E o mais importante, vais aprender a fazer isso de uma forma simples e eficiente. Vamos mergulhar!

Entendendo as Diferenças entre Python 2 e Python 3

Antes de entrarmos completamente nos truques para a transição do Python 2 para o Python 3, é essencial que compreendas as principais diferenças entre estas duas versões. O Python 3 introduz alterações na linguagem que não são retrocompatíveis. Esta é a principal razão pela qual o processo de migração pode ser complicado.

Por exemplo, no Python 2, o comando print é usado sem parênteses, enquanto no Python 3, os parênteses são necessários. No Python 2.7 poderias usar:

print "Olá, mundo!"

No Python 3.7 ou superior, deverias escrever assim:

print("Olá, mundo!")

Usando Bibliotecas Específicas do Python 3

O Python 3 traz consigo uma série de novas bibliotecas que não estão disponíveis no Python 2.7. Portanto, precisarás de alterar as tuas importações para corresponderem às bibliotecas do Python 3. Por exemplo, se usavas urlib2 antes, agora terás que importar urllib.request, urllib.parse, e urllib.error.

Aqui está um exemplo de como o teu código deve ficar:

# Python 2.7
import urllib2
response = urllib2.urlopen('http://python.org/')
html = response.read()

# Python 3.7
import urllib.request
response = urllib.request.urlopen('http://python.org/')
html = response.read()

Mudança na Sintaxe da Exceção

Uma das mudanças mais notáveis entre o Python 2 e o Python 3 é a forma como as exceções são tratadas. No Python 2, a sintaxe except Exception, e: era utilizada. Mas no Python 3, deves mudar para except Exception as e:. Aqui está um exemplo de como fazer isso:

# Python 2.7
try:
    ...
except Exception, e:
    print e

# Python 3.7
try:
    ...
except Exception as e:
    print(e)

A Função map()

A função map() no Python 2 retorna uma lista, enquanto no Python 3 retorna um objeto iterável. Então, se quiseres obter uma lista como resultado, deves converter explicitamente o resultado para uma lista usando a função list(). Aqui está um exemplo:

# Python 2.7
result = map(func, values)

# Python 3.7
result = list(map(func, values))

Lidando com a Divisão no Python

No Python 2, a divisão de dois inteiros resulta num número inteiro. No Python 3, no entanto, a divisão de dois inteiros resulta num número de ponto flutuante. Quando estiveres a migrar o teu código, é essencial ter isto em conta. Veja o exemplo abaixo:

# Python 2.7
result = 5 / 2  # O resultado é 2

# Python 3.7
result = 5 / 2  # O resultado é 2.5

A Biblioteca __future__

A biblioteca __future__ pode ser a tua melhor amiga durante a migração. Esta permite que uses as funcionalidades do Python 3 no teu código Python 2.7, tornando a tarefa de migração muito mais fácil. Por exemplo, podes usar a função print() do Python 3 no teu código Python 2.7 assim:

from __future__ import print_function
print("Olá, mundo!")

Compreensões de lista e Escopo de Variável

Outra alteração importante no Python 3 é a forma como lida com o escopo de variáveis em compreensões de lista. No Python 2, as variáveis usadas em compreensões de lista vazam para o escopo principal. O Python 3 corrigiu este problema encapsulando o escopo da variável dentro da compreensão da lista. Aqui está um exemplo:

# Python 2.7
x = 1
print [x for x in range(5)]
print x  # Isto imprime 4, não 1

# Python 3.7
x = 1
print([x for x in range(5)])
print(x)  # Isto imprime 1

As Chaves do Dicionário são Visualizações no Python 3

No Python 3, dictionary.keys(), dictionary.values(), e dictionary.items() retornam objetos de visualização em vez de listas. Se precisares de obter uma lista, deverás converter o resultado numa lista explicitamente. Vê o seguinte exemplo:

# Python 2.7
dictionary = {'um': 1, 'dois': 2}
keys = dictionary.keys()  # Isto é uma lista

# Python 3.7
dictionary = {'um': 1, 'dois': 2}
keys = list(dictionary.keys())  # Agora isto é uma lista
Adeus a xrange()

No Python 3, a função xrange() foi substituída por range(), que agora retorna um objeto iterável. No Python 2.7, se quiseres obter uma lista a partir de range(), precisas de a converter explicitamente numa lista:

# Python 2.7
x = xrange(10)  # Isto é um iterável

# Python 3.7
x = list(range(10))  # Isto é uma lista

Códigos de Escape em Strings

O Python 2 permite o uso de códigos de escape em strings não formatadas, enquanto que o Python 3 não permite. Se quiseres usar códigos de escape no Python 3, precisas de usar strings formatadas. Aqui está como fazer isso:

# Python 2.7
x = '\100'

# Python 3.7
x = r'\100'

Arredondamento em Python

As funções de arredondamento também se comportam de forma diferente em Python 2 e Python 3. No Python 2, round(0.5) é igual a 0.0 e round(1.5) é igual a 2.0. No entanto, Python 3 segue o método de arredondamento para o número par mais próximo, também conhecido como arredondamento de banqueiro. Aqui está um exemplo:

# Python 2.7
print(round(0.5))  # Isto imprime 0

# Python 3.7
print(round(0.5))  # Isto imprime 1

Alterações nos Operadores de Comparação

No Python 2, poderias comparar objetos não ordenáveis. Python 3 lançará uma exceção nesses casos. Portanto, deverás rever o teu código para garantir que não estás a tentar comparar objetos não ordenáveis. Por exemplo:

# Python 2.7
print(1 < '1')  # Isto é True

# Python 3.7
print(1 < '1')  # Isto lança uma exceção TypeError

Usando next()

A função next() é usada para obter o próximo item de um iterador. No Python 2, poderias usar o método iterator.next(). No Python 3, deverás usar a função next(iterator). Aqui está um exemplo:

# Python 2.7
iterator = iter([1, 2, 3])
print iterator.next()  # Isto imprime 1

# Python 3.7
iterator = iter([1, 2, 3])
print(next(iterator))  # Isto imprime 1

Codificação Padrão

Python 2 usa ASCII como a codificação padrão, enquanto Python 3 usa UTF-8. Isso pode causar problemas se o teu código Python 2 manipular strings que não são ASCII. Eis como podes lidar com isso em Python 3:

# Python 2.7
string = '¡Hola, mundo!'

# Python 3.7
string = '¡Hola, mundo!'

__eq__() ou __cmp__()?

No Python 2, poderias implementar o método __cmp__() nas tuas classes para realizar comparações entre objetos. Python 3 elimina este método e em vez disso, deverás implementar os métodos __eq__() e __lt__() para igualdade e comparação respetivamente. Aqui está um exemplo:

# Python 2.7
class Test(object):
    def __cmp__(self, other):
        return self.value - other.value

# Python 3.7
class Test(object):
    def __eq__(self, other):
        return self.value == other.value

    def __lt__(self, other):
        return self.value < other.value

Alterações nas Variáveis de Classe

No Python 2, as variáveis de classe são acessíveis através da instância da classe. No Python 3, não podes mudar as variáveis de classe através da instância. Portanto, ao migrar o teu código Python 2 para Python 3, deverás ter isto em conta. Aqui está um exemplo:

# Python 2.7
class Test(object):
    valor = "Olá, mundo!"

    def mudar_valor(self, novo_valor):
        self.valor = novo_valor

teste = Test()
teste.mudar_valor("Adeus, mundo!")
print(teste.valor) # Isto imprime: Adeus, mundo!

Python 3.7
class Test(object):
    valor = "Olá, mundo!"

    def mudar_valor(self, novo_valor):
        self.valor = novo_valor
        
teste = Test()
teste.mudar_valor("Adeus, mundo!")
print(teste.valor) # Isto imprime: Olá, mundo!
print(Test.valor) # Isto imprime: Adeus, mundo!

Adicionando *args e **kwargs nos Métodos de Classe

Python 2 permite que os métodos de classe aceitem um número arbitrário de argumentos posicionais e de palavras-chave, mesmo que não estejam definidos no método. Python 3 não permite isso, por isso deverás garantir que incluis *args e **kwargs na definição do método se quiseres que ele aceite um número arbitrário de argumentos. Aqui está um exemplo:

# Python 2.7
class Test(object):
    def metodo(self, x):
        print(x)

teste = Test()
teste.metodo(1, 2, 3)  # Isto é válido

# Python 3.7
class Test(object):
    def metodo(self, x, *args, **kwargs):
        print(x, args, kwargs)

teste = Test()
teste.metodo(1, 2, 3)  # Isto é válido

Iteradores em Python 3

Em Python 2, os métodos dict.iterkeys(), dict.itervalues() e dict.iteritems() retornam iteradores. Python 3 os substitui por dict.keys(), dict.values(), e dict.items(), que retornam visualizações de dicionários. Mas não te preocupes, porque estes também são iteráveis e podes convertê-los em listas, se necessário.

# Python 2.7
dicionario = {'um': 1, 'dois': 2}
for chave in dicionario.iterkeys():
    print(chave)

# Python 3.7
dicionario = {'um': 1, 'dois': 2}
for chave in dicionario.keys():
    print(chave)

Com todos estes truques, estou certo de que a tua migração do Python 2.7 para o Python 3.7 será mais suave. Não te esqueças de que migrar o teu código para o Python 3 não é apenas importante pelas melhorias que oferece, mas também porque o Python 2 já não é oficialmente mantido. Boa sorte na tua jornada rumo ao Python 3!

Deixe um comentário