Nota Técnica #59

Por Tessa Hayman

Maio 2021

Introduzimos a opção de escolher usar o Aimsun Next com Python 3 na última versão, Aimsun Next 20. Entretanto, há algumas diferenças importantes a serem observadas entre Python 2 e Python 3 quando você começa a converter seus modelos e scripts. Esta nota técnica cobrirá as principais diferenças e como atualizar seu script em Python 2 para prepará-lo para Python 3.

Em janeiro de 2020, Python 2 atingiu o status de fim de vida, o que significa que não receberá mais atualizações ou correções de bugs e, o que é importante, nenhuma correção de segurança. Portanto, recomendamos que você utilize o Python 3 para todos os novos desenvolvimentos. Muito código Python 3 no software Aimsun é utilizável também no Python 2. Entretanto, você pode descobrir que seu script antigo dá erros quando usado com Python 3 – particularmente no que diz respeito a instruções de impressão!

Além de declarações de impressão, é bom estar ciente das principais diferenças para que você possa verificar o que precisa ser alterado se você desejar usar o mesmo script ou função de custo em vários modelos, pois algumas alterações podem alterar seu script sem dar um erro.

Print 

A mudança mais comum que você verá é com funções print. No Python 3, a função de impressão deve estar entre parênteses.

Python 2
print “hello”
Python 3
print (“hello”)

Divisão de Inteiro 

No Python 2, quando duas variáveis inteiras fossem divididas, um valor inteiro seria gerado. Entretanto, no Python 3, isto foi alterado para que um valor flutuante fosse dado como saída, o que protege contra um lugar comum de confusão para os usuários.

Isto pode ter um impacto significativo se você tiver uma divisão inteira em seu script.

Python 2
5/3=1
Python 3
5/3=1.6666...

Unicode 

Na Python 2, você tinha que especificar se uma string deveria ser armazenada como Unicode usando “u” antes da string. No Python 3, Unicode é agora o método padrão de armazenamento de strings

Python 2
u“café”
Python 3
“café”

Iterate over a range 

xrange() é frequentemente usado em Python 2 para iterar sobre um conjunto de objetos em uma lista ou em um for-loop. É útil para operações únicas, mas pode se tornar ineficiente se for repetido várias vezes à medida que se repete a geração do intervalo. Também não pode ser usado com funções aplicadas a listas. Portanto, ele foi substituído por range(), que gera um objeto range que funciona mais como uma lista.

Python 2
for x in xrange():
Python 3
for x in range():

Iterate over dict 

A iteração sobre as chaves de um dicionário foi alinhada para ser a mesma que a iteração sobre uma lista. .iterkeys() não é mais necessário e, em vez disso, pode-se iterar diretamente sobre as chaves. Para iterar sobre os valores, você pode usar .values() em vez de itervalues().

Python 2
for x in dict.iterkeys():
for x in dict.itervalues():
Python 3
for x in dict:
for x in dict.values():

Raise exceptions 

As exceções podem ser criadas para alertar o usuário sobre um erro e dizer ao script o que fazer no caso de um erro. No Python 3, esta exceção deve ser colocada entre parênteses.

Python 2
raise IOError,file error”
Python 3
raise IOError(file error”)
Handling exceptions 

Try e except são usados para testar e lidar com erros de código. O bloco de try permite que você teste um bloco de código para erros, enquanto o bloco de except permite que você lide com o erro. Você pode especificar na exceção para fazer uma determinada ação se um erro nomeado for levantado. A sintaxe da exceção foi alterada em Python 3 para incluir “as”.

e.g.  

try:

print(x)

except NameError as err:

print("x is not defined")

print(err)

except:

print("Something else")

A sintaxe da linha de exceção foi alterada para incluir um “as” e este exemplo imprimiria o seguinte:

x is not defined 

name ‘x’ is not defined 

Python 2
except NameError, err:
Python 3
except NameError as err:

Next() 

Next permite devolver o próximo item em uma iteração. Anteriormente no Python 2 podia ser especificado usando List.next() e next(List) mas no Python 3 somente a última sintaxe é possível.

Python 2
X=next(List) or
X=List.next()
Python 3
X =next(List)

Namespace leaks 

No Python 2, era possível que a variável iterada utilizada em um for-loop fosse divulgada no namespace global. Ou seja, se você usasse o mesmo nome de variável antes e depois do for-loop, a variável for-loop poderia sobrescrever esse valor com o valor final para a variável no loop.

e.g.  

variable = 0
print 'before: variable =', variable
print 'for-loop: ', [variable for variable in range(5)]
print 'after: variable =', variable
Python 2
before: variable = 0
for-loop:  [0, 1, 2, 3, 4]
after: variable = 4
Python 3
before: variable = 0
comprehension: [0, 1, 2, 3, 4]
after: variable = 0