GEOG 489
Advanced Python Programming for GIS

1.2 Differences between Python 2 and Python 3

PrintPrint

If you have taken GEOG 485 before we changed it from ArcGIS Desktop to Pro or you learned about Python programming and customization of ArcGIS Desktop in some other context, then you have been working with arcpy under Python version 2. ArcPy is also available in ArcGIS Pro, but everything here runs under Python version 3. This is why we start this first lesson of the course with an overview on the differences between Python 2 and Python 3.

Python 3.0 was released in 2008 and the final version of 2.7 was released in mid-2010, so they have both been around for a long time. There are no major developments planned for Python 2, with all the attention focused on Python 3.

While a lot of the changes from Python 2 to Python 3 were in the background or with special features that we won’t need in this course, there are a few changes that you are somewhat likely to encounter and that we, therefore, list on the following pages.

In addition, while many things in the ArcGIS Pro version of arcpy still work in the same way as in the version you might know from ArcGIS Desktop, there are some differences, in particular with respect to the availability of certain modules and tools. This won’t be a concern in this first lesson, but we will examine the differences in the following section. 

You might wonder why we're talking about old versions of Python and ArcGIS Desktop and it's a fair question. At some point, you may want to run some pre-existing Python 2 code in ArcGIS Pro for any number of reasons that might include updating legacy tools, converting old code, using new ArcGIS Pro tools, sharing with ArcGIS Pro users, using Python 3 libraries, importing a legacy MXD from ArcGIS Desktop or perhaps using the better performance, which may come from using either multiprocessing or 64 bit processing (although these are also available in Python 2 and you can experiment with those later in the lesson). There's a reasonable chance you're going to be exposed to this older Python 2 code at some point and when that happens we want you to know how to update it easily.

print ... vs. print(...)

There are several differences between Python 2 and 3, but the most obvious one is that the print statement from Python 2 is now a function in 3. You might recall from GEOG 485 that a function takes parameters (and sometimes returns a value).

Have a look at the example below for a simple illustration of this change. You’ll notice that for Python 2 both will work. Usually, though, most people have written code using the standard Python 2 print statement, not the way which appears to support print as a function.

#Python 2 
print "Hello World" 
print ("Hello World") 
#Python 3 
print ("Hello World")

All of the more complicated things that we can do with a print statement such as adding in variables or using the .format statement can be implemented just the same. If you're unfamiliar with .format we will look at it in more detail soon.

#Python 2 
Name = "James" 
print "Hello World. My name is " + Name 
print "Hello World. My name is {0}".format(Name) 
#Python 3 
Name = "James" 
print ("Hello World. My name is " + Name) 
print ("Hello World. My name is {0}".format(Name))

You can experiment with creating more complicated versions of those print statements or functions depending on which version of Python you’re using. In the class, if we’re describing print, we will be using the terms statement and function interchangeably – be sure to adjust your code according to the version of Python you’re using. Be aware that you can use the Python 3 version in Python 2.7 and many programmers have transitioned to using this approach over time (but you'll potentially still see print used as per our Python 2 examples above).

For the technically-minded, I mentioned above that in Python 2 print appears to work as a function but it’s actually being interpreted by Python as (“Hello World”) which is equivalent to “Hello World” in Python.

Integer division

In Python 2, the result of a division between two integer numbers was again an integer number, namely the result with everything after the decimal point truncated. So for instance, the result of the expression

1 / 2

is the integer number 0. If you wanted to have the result as a floating point number you had to use something like 1 / float(2) or 1 / 2.0 to first turn one of the operands into a float. This behavior has changed in Python 3. The result is now a floating point number, so 0.5 in this case.

Strings

Python 2 had two different string data types, str() for ASCII strings (so only providing for a very limited set of different characters but also only requiring one byte per character) and unicode() for Unicode strings allowing for a much larger set of characters and supporting writings that are not Latin-based such as Chinese characters for example. To create a Unicode string you had to use the prefix u like this: u'some string'. You might remember this u appearing in front of some output in Python 2, for instance from arcpy functions such as ListFeatureClasses().

In Python 3, everything within quotes is considered a unicode UTF-8 string, so you can write

print('Saying hello in Chinese: 你好')

As in Python 2, Unicode characters can be written with a \u followed by their 4 or 8 digit hexadecimal number if you have no other way of entering the characters into the code. So the previous command can also be written as:

print('Saying hello in Chinese: \u4f60\u597d')

In case you have not heard much about the Unicode standard for encoding characters, here is a good article explaining what this is all about: A Beginner-Friendly Guide to Unicode.

Reorganization of the Python standard library

With the change to Python 3, the modules from the standard library have been reorganized. As a result, the import statements used in a Python 2 script may not work anymore because the names of modules have changed, etc. For instance, in Python 2 the standard library contains the modules urllib and urllib2 for working with URLs and accessing content on the web. In Python 3, the functionality has been reorganized into three submodules called urllib.parse, urllib.request, and urllib.error. There are more examples like this and also examples of individual functions or classes that have a changed name or have been removed entirely.

If you want to dive deeper into this topic, have a look at the page "What's New in Python 3.0" from the Python documentation and this article summarizing the key differences between Python 2 and 3.

Differences between ArcGIS Desktop and ArcGIS Pro's arcpy functions.

There are some differences in the level of functionality available in arcpy in Desktop when compared to Pro. These are documented in the Pro help here and here. Probably the one most likely to trip up those of you with existing scripts is the renaming of arcpy.mapping to arcpy.mp which will require some changes to code (including any function calls to arcpy.mapping.<name> functions). 

There is also a list of tools which are not supported in Pro which aren't commonly used but could have specialty tools that rely on them. These tools include Coverage (arcpy.arc), Data Interoperability (arcpy.interop), Parcel Fabric (arcpy.fabric), Schematics (arcpy.schematics), and Tracking Analyst (arcpy.ta). If you're migrating from Desktop to Pro in your professional lives, it might be worthwhile checking that none of your scripts or workflows require these tools.

In addition to these entire toolboxes which are no longer available in Pro, a number of individual tools within toolboxes have either not been implemented or haven't been implemented yet. We won't repeat that long list here, but it may be worth having a quick look over the list (this is the second link from two paragraphs above) to double-check that any of your necessary or favorite tools aren't in the list.

There are also both new and improved tools within Pro that don't exist within Desktop. Some of these take advantage of parallel processing or are written more efficiently and therefore perform better than their legacy (old) versions. When using Pro you'll often see a small tooltip in the top of the Geoprocessing window mentioning that another tool offers improved performance or additional functionality.