Python Programming Style Guide

 

Statement Structure

Program StructurePython Style GuideNaming Conventions

While Python is very flexible in terms of program and code structure, the way in which some statements are formatted can help make your code more readable and easier to comprehend. Just because the syntax of the language allows you to do something, doesn't mean it's the best choice to employ when attempting to create a well structured program. This page describes a number of specific examples that should be applied anytime you are writing a computer program. Be sure to also review the "readability" section related to proper vertical and horizontal spacing.

Boolean Literals

A boolean literal should never appear within a logical expression. That is, you should never compare against the values True or False.

if result == True :           # Don't do this.
  print("We are done.")

if result is True :           # Don't do this.
  print("Very Bad!!")

Instead, you should choose meaningful variable names that implies a specific condition. When naming a variable that stores a boolean value, the name should include a verb.

if validResult :              # Do this.
  print("We are done.")

Of course boolean literals can be used in your program, just not within a logical expression. For example, you may need to assign a value to boolean variable

validResult = False

or return boolean from a function.

def isValid( value ):
  if value > 0 and value <= 100 :
    return True
  else :
    return False

Aliases

When one variable is assigned to another, a duplicate copy of the object is not created. Instead, the second variable becomes an alias of the first. That is, the object to which the first variable references is now known by two names.

value = 5       # value refers to an integer object containing 5.
small = value   # small is an alias of the same object.

Python provides the is and is not operators for testing whether two variables refer to the same object. These operators should be used to test for aliases,

if small is value :        # Read this as:  if small is an alias of value.
  print("It's an alias.")

The equality (==) operator should only be used to test whether two objects contain the exact same value(s).

if small == value :        # Don't do this to test aliases.
  print("Don't do this.")

Always use is or is not when comparing against the null reference None.

while curNode is not None :   # Do this.
  ....
if curNode == None :       # Don't do this.
  ....

Do not use equality to test for aliases and do not use the is and is not operators to test for equality.

Typecasting

Since Python only extracts user input as a string, we have to convert the string to an integer or floating-point value when a numerical value is needed. For readability and to maintain good form, the input string should be converted to the appropriate numerical value as soon as it is extracted.

userInput = input("Enter a grade: ")        # Do this
grade1 = int(userInput)
userInput = input("Enter a grade: ")
grade2 = int(userInput)
userInput = input("Enter a grade: ")
grade3 = int(userInput)

You can combine the extraction and the conversion into a single nested statement

grade1 = int(input("Enter a grade: "))      # or do this
grade2 = int(input("Enter a grade: "))
grade3 = int(input("Enter a grade: "))

Do not wait and convert the string to a numerical value when it's needed in a calculation.

grade1 = input("Enter a grade: ")           # Don't do this
grade2 = input("Enter a grade: ")
grade3 = input("Enter a grade: ")
     . . . .
avgGrade = (int(grade1) + int(grade2) + int(grade3)) / 3

Loop Variables

Simple or single letter variable names (i, a, b, etc) are appropriate when used with a loop involving integer values as would be done in mathematics.

for i in range(1, 11) :
  . . . .

for k in range(n) :
  . . . .

But they are not appropriate when iterating over the contents of a container.

for i in string :            # Don't do this.

Use a meaningful name for the loop variable

for letter in string :       # Do this.

such that when the statement makes sense when read "for each letter in string".

Count-Controlled Loops

Do not use the enumerate() function to iterate through a collection.

for index, value in enumerate(myList) :     # Don't do this.
  print(index, value)

Use a count-controlled loop instead.

for index in range(len(myList)) :     # Do this.
  print(index, myList[index])

The Range Function

Never use the range() function within a logical expression

if i in range(1, 11) :      # Don't do this.
   Do something

You should compare the extremes of the range directly

if i >= 1 and i <= 10 :     # Do this.
   Do something

Returning Multiple Values

Python allows you to return multiple values from a function or method by returning a tuple that contains the values. When returning multiple values from a function or method, the returned values must be assigned to individual variables.

found, position = self._findPosition(value)   # Do this.
if found :
  # do something.
else :
  # do something else.

Do not assign the resulting tuple to a single variable and then access the values using subscripts.

result = self._findPosition(value)   # Don't do this.
if result[0] :  # result[0] has no meaning.
  # do something.
else :
  # do something else.

Note: This only applies when the function or method is simply using a tuple to return multiple values. If the function or method is suppose to return a legitimate tuple, it can be assigned to a single variable.

Operator Methods

A user-defined class can define a method to implement any of the standard Python operators. Operator methods, which are named with a double underline preceding and following a text name (__eq__), are automatically called when the corresponding operator (==) is used.

Do not call an operator method by name, instead use the corresponding operator. For example, when testing if an item is contained in a container, you should do the following

if item in myBag :               # do this
  .......

instead of calling the method directly

if myBag.__contains__(item) :    # don't do this
  .......

Opening a File

Do not combine the opening of a file with any other operation. It should be specified as a separate statement. For example, you should do the following

filename = input("Enter a filename: ")
inFile = open(filename, "r")                          # do this

and not combine the open() with other statements:

inFile = open(input("Enter a filename: "), "r")    # don't do this


for lines in open(filename, "r"):                  # don't do this
   ......

List Comprehensions

You may not use list comprehensions for Python programs in this course. For example, the following is not allowed:

squares = [x ** 2 for x in range(10)]

Instead, you must use an explicit loop that appends the values:

squares = []
for x in range(10) :
  squares.append(x ** 2)

Empty Containers

ADT Provides isEmpty()

When evaluating an instance of a container to determine if it is empty or not and the ADT provides both a length and empty (or isEmpty) operation, you should use isEmpty(). For example, the following

while not myQueue.isEmpty() :      # Do this.
   ......

is more readable than the alternative

while len(myQueue) != 0 :          # Don't do this.
   ......

The use of the length operation should be reserved when you actually need to know the length or size of the container. For example

numItems = len(myQueue)
print( "My queue contains", numItems, "items" )
ADT Only Provides len()

If a container only provides the length operation (i.e. Python's list, dictionary, set), then you have to use it for both extracting the number of elements in the container and to determine if it's empty.



Program StructurePython Style GuideNaming Conventions
Print -- Recent Changes
Page last modified on March 22, 2013, at 08:50 AM