By Tessa Hayman
We introduced the option to choose to use Aimsun Next with Python 3 in the latest version, Aimsun Next 20. However, there are some important differences to be aware of between Python 2 and Python 3 when you begin to convert your models and scripts. This technical note will cover the key differences and how to update your Python 2 script to get it Python 3–ready.
In January 2020, Python 2 reached end–of-life status, which means it will receive no further updates or bug fixes and, importantly, no security fixes. We therefore recommended that you use Python 3 for all new development. A lot of Python 3 code in Aimsun software is useable also in Python 2. However, you may find that your old script gives errors when used with Python 3 – particularly with respect to print statements!
In addition to print statements, it’s good to be aware of the major differences so you can check what needs to be changed if you did wish to use the same script or cost function on multiple models as some changes may change your script without giving an error.
The most common change you will see is with print statements. In Python 3, the print statement should be in brackets.
In Python 2, when two integer variables were divided, an integer value would be generated. However, in Python 3 this has been changed so that a float value is given as an output, which protects against a common place of confusion for users.
This could have a significant impact if you have integer division in your script.
In Python 2, you had to specify if a string was to be stored as Unicode using “u” before the string. In Python 3, Unicode is now the default storage method of strings
xrange() is often used in Python 2 to iterate over a set of objects in a list or set in a for-loop. It is useful for one-time operations but can become inefficient if its repeated multiple times as the generation of the range is repeated. It also can’t be used with functions applied to lists. Therefore, it has been replaced with range(), which generates a range object which works more like a list.
for x in xrange():
for x in range():
Iteration over the keys of a dictionary has been aligned to be the same as iterating over a list. .iterkeys() is no longer needed and instead you can iterate directly over the keys. To iterate over the values, you can use .values() rather than itervalues().
for x in dict.iterkeys(): for x in dict.itervalues():
for x in dict: for x in dict.values():
Exceptions can be raised to alert the user to an error and tell the script what to do in the case of an error. In Python 3 this exception must be put into brackets.
raise IOError, “file error”
raise IOError(“file error”)
Try and except are used to test and handle errors in code. The try block allows you to test a block of code for errors whereas the except block lets you handle the error. You can specify in the except to do a certain action if a named error is raised. The syntax for the except statement has been altered in Python 3 to include “as”.
try: print(x) except NameError as err: print("x is not defined") print(err) except: print("Something else")
The syntax of the except line has been altered to include an “as” and this example would print the following:
x is not defined
name ‘x’ is not defined
except NameError, err:
except NameError as err:
Next allows you to return the next item in an iterator. Previously in Python 2 it could be specified using List.next() and next(List) but in Python 3 only the latter syntax is possible.
X=next(List) or X=List.next()
In Python 2, it was possible for the iterated variable used in a for-loop to leak into the global namespace. Or namely, if you used the same variable name before and after the for-loop, the for-loop variable could overwrite that value with the final value for the variable in the loop.
variable = 0 print 'before: variable =', variable print 'for-loop: ', [variable for variable in range(5)] print 'after: variable =', variable
before: variable = 0 for-loop: [0, 1, 2, 3, 4] after: variable = 4
before: variable = 0 comprehension: [0, 1, 2, 3, 4] after: variable = 0