Classes and Inheritance: Part One

classesIn the previous article, we introduced some hashing functions, but had to pass the number of buckets (numBuckets) to each function, which was not an ideal solution. In this article, we introduce a programming construct that will provide a better way of working with these hashing functions: classes.

Classes Defined

A class is an extensible program-code-template for creating objects, providing initial values for member variables and implementations of functions. When an object is created by a constructor of the class, the resulting object is called an instance of the class, and the member variables specific to the object are called instance variables (unlike class variables, which are variables that are shared across the class).

Classes are essentially combinations of variables and functions. We use the word “encapsulation” to refer to this combination. The variables either belong to the class or specific instances of the class. The functions are subroutines with the ability to operate on objects or classes. Many kinds of functions exist. In most programming language, there are constructors (functions automatically called when an instance of the class is created), destructors (functions automatically called when an instance of the class is deleted or otherwise destroyed), and conversion operators (functions that define how certain operators, e.g. the equality operator, work with instances of the class).

Classes: Implementation in Python

In Python, the simplest form of a class definition looks like this:

class HashObject:
	
	...
	

Class definition must precede any instantiation of the class to have any effect. The statements inside a class definition will usually be function definitions, but other statements are allowed. The function definitions inside a class normally have a peculiar form of argument list, dictated by the calling convention for functions.

Class objects support attribute references and instantiation. Attribute reference use the standard syntax used for all attribute references in Python: obj.name. If the class definition looked like this:

class HashObject:
	i = 123
	def myfunc(self)
		return 'A simple function definition'

then HashObject.i and HashObject.myfunc are valid attribute references. Class attribute can be assigned, so you can change the value of HashObject.i by assignment.

Class instantiation uses function notation; just pretend that the class object is a parameterless function that returns a new instance of the class. For example,

h = HashObject()

creates a new instance of the class HashObject and assigns this object to the local variable h.

The instantiation operation creates an empty object. Many classes like to create objects with instances customized to a specific initial state. Therefore, a class may define a special method, called a constructor. Here is an example:

def __init__(self):
	self.data = []

When a class defines an __init__() method, class instantiation automatically invokes __init__() for the newly-created class instance. In the case of HashObject, a new, initialized instance can be obtained by:

h = HashObject()

The __init__() method may have arguments for greater flexibility. In that case, arguments given to the class instantiation operator are passed on to init. For example:

class HashObject:
   def __init__(self, num):
      self.numBuckets = num

>>> h = HashObject(51)
>>> x.numBuckets
51

With instance objects, there are two kinds of valid attribute names, data attributes and methods. Data attributes correspond to data members in C++. Like local variables, they do not need to be declared and spring into existence when they first have a value assigned to them. For example, if we created an instance of HashObject called h, we can create and print out the value of x like so:
>>> h.x = 123
>>> print(‘h.x = ‘,h.x)
123
The other kind of instance attribute is a method. A method is a function that belongs to an object. Valid method names of an instance object depend on its class. By definition, all attributes of a class that are function objects define corresponding methods of its instances.

Usually, a method is called right after it is bound. Suppose we add a function definition to HashObject:

class HashObject:
    def test(self):
        print('Hello, world!')

We can call the method in object h like so:
>>> h.test()
Hello, world!

Notice that h.test() was called without an argument, even though the function definition for test() specifies an argument. This is where Python deviates from C++. In this example, the call h.test() is exactly equivalent to HashObject.test(h). In general calling a method with a list of n arguments is the same as calling the corresponding function with an argument list that is created by inserting the method’s object before the first argument.

Python classes also supports inheritance. The syntax for a derived class definition looks like this:

class DerivedClass(BaseClass):
	
	...
	

When the class object is constructed, the base class is remembered. If a requested attribute is not found in the class, the search proceeds to look in the base class. This rule is applied recursively if the base class itself is derived from some other class.

If we create an instance of DerivedClass, method references are resolved as follows: the corresponding class attribute is searched, descending down the chain of base classes if necessary, and the method reference is valid if this process yields a function object. Derived classes may also override methods of their base classes. Because methods have no special privileges when calling other methods of the same object, a method of a base class that calls another method defined in the same base class may end up calling a method of a derived class that overrides it. This is similar to virtual functions in C++, where a function is left undefined in the base class but defined in one or more derived classes.

Python also supports a form of multiple inheritance as well. A class definition with multiple base classes looks like this:

class DerivedClass(BaseClass1, BaseClass2, BaseClass3)
	
	...
	

The search for attributes is depth-first, left to right, so if an attribute is not found in the derived class, it is searched for in BaseClass1, then the base classes of BaseClass1, then BaseClass2, and so on. It should be mentioned that the multiple inheritance method resolution in Python uses a dynamic algorithm to linearize the search order, both preserving the search order, and ensuring that each parent is called only once.

One significant way in which Python classes differ from C++ classes is that there is no means of declaring functions or variables to be private or protected. Thus, there are no private variables in Python. The closest you’ll get are variables that start with a double underscore, like __variable. Such a variable cannot be directly referenced outside the class definition, at least not directly. Thus, if we have something like this:

class HashObject:
	def __init__(self, num):
		__numBuckets = num

and we create an instance of HashObject:

>>> h = HashObject(47)

We can’t access __numBuckets directly:

>>> print(h.__numBuckets)

will result in an error message.

Now that we have a solid foundation for understanding Python classes, we should be able to rewrite our hash functions from the previous article as a class. We will do that in the next article.

External Links:

Classes Tutorial on python.org

Class (computer programming) on Wikipedia

Python Programming: Part Two (Python IDLE)

Python IDLEIn the previous article, we introduced some basic concepts about Python and how to use Python at the interactive command line. In this article, we will introduce variables, and also consider how to save a code module and run it, both from the command line and the Python IDLE interface.

The previous article contained the following Python statement:
>>>> a = 3+4

This was our first example of a Python variable. As you may have deduced, in Python, unlike C/C++ or some other languages, you don’t have to declare variables separately. You declare a variable when you use it for the first time. There are three distinct numeric types: integers, floating point numbers, and complex numbers. In addition, Booleans are a subtype of integers.

Numbers are created by numeric literals or as the result of built-in functions and operators. Unadorned integer literals yield integers. For example:
>>> x = 10

yields an integer variable x. Numeric literals containing a decimal point or an exponent sign yield floating point numbers. For example:
>>> x = 3.5

yields a floating point variable x.

You can also create a complex number. Appending ‘j’ or ‘J’ to a numeric literal yields an imaginary number to which you can add an integer or float to get a complex number with real and imaginary parts. For example:
>>> x = 10j + 5

creates a complex number with 5 as the real part and 10 as the imaginary part. You can retrieve both parts by typing:
>>> print(x)

or just the real or imaginary parts:
>>> print(x.real)
>>> print(x.imag)

The variables real and imag, however, are read-only variables and cannot be used to change the values of the real and imaginary components. The constructors int(), float() and complex() can be used to produce numbers of a specific type. For example:
>>> x = int(23)

creates an integer with a value of 23. Interestingly, leaving the parameter blank like this:
>>> x = int()

results in the value 0 being assigned to x.

Textual data in Python is handled with str objects, or strings. Strings are immutable sequences of Unicode code points. String literals can be written in several different ways – single quoted, double quoted, or triple quoted:
>>> text = ‘This is a test’
>>> text = “This is a test”
>>> text = ”’This is a test”’
>>> text = “””This is a test”””

Strings are immutable sequences of Unicode code points. Therefore:
>>> text[0] = ‘B’

is not allowed. However, if we want to print a single character from the string, we can do this:
>>> print(text[0])

or, if we want to print multiple characters that represent a subset of the string, we can specify two indices separater by a colon. For example:
>>> print(text[0:3])

will result in ‘This‘ being printed.

So far, we have been typing in programs at the interactive prompt, which has one big disadvantage: programs you type there go away as soon as the Python interpreter executes them. Because the code typed in interactively is never stored in a file, you cannot run it again without retyping it. To save programs permanently, you need to write your code in files, which are usually called modules. Modules are text files containing Python statements. Once a module is coded and saved in a file, you can ask the Python interpreter to execute the module any number of times.

To code a module, open your favorite text editor (e.g. Notepad in Windows, perhaps vi, emacs or gedit in Linux) and type some statements into a new text file called module01.py:

# My first Python script
name = str(input(‘Please enter your name: ‘)) # Read some input
print(‘Welcome to Python, ‘+name) # Print something out

In this module, we introduced three new concepts. The first line of the module is a comment. A hashtag (#) introduces a comment, which is just a description of what the program is doing. Comments can appear on a line by themselves or to the right of a statement. Multiline comments can be added, but must begin and end with three single quote marks, like this:
”’This is an example
 of a multi-line comment that can be inserted into a Python script on the command line or in the Python IDLE interface”’

The other concept we introduced was the input function. input() simply reads characters from the standard input device (in this case, a keyboard). We used the str() constructor to ensure that name is created as a string.

The third concept we introduced was the plus sign (+) to concatenate the literal string ‘Welcome to Python, ‘ and name. As you probably guessed, the program will read in a string from the keyboard representing the user’s name, and will print out a welcome message containing the user’s name.

Once you have saved this text file, you can ask Python to run it by listing its full filename as the first argument to a python command, typed at the system command prompt; e.g.:
> python module01.py

Using the Python IDLE Interface to Run a Module

Python IDLE

Python IDLE interface running our simple script.

Alternatively, from the Python IDLE interface, you can navigate to File -> Open, and then browse to module01.py and open it. A new window should appear with the code for the module in it. Navigate to Run -> Module (or in Windows, just press F5) to run the module, and the output should appear in the main IDLE window, after it prints the “RESTART” banner message:

Please enter your name: Grumbledook
Welcome to Python, Grumbledook

There are other ways we can load a module. We could use the import command, assuming the module is within Python’s path:

>>> import module01

If we make changes to the code, we would have to use the reload command in order for them to take effect:

>>> from imp import reload
>>> reload(module01)

Finally, we could use the exec() and open.read() commands in conjunction to simultaneously load and run the module:

>>> exec(open(‘module01.py’).read())

These three options should work both at the command line and in the Python IDLE interface.

In the next article, we will introduce some additional concepts and also code our first Python function.

External Links:

Wikipedia article on Python IDLE interface

Python IDLE website

Python IDLE wiki

How to Install Python IDLE on Linux

How to Install Python IDLE on eHow

Python Programming: Part One

Python programmingPython, as mentioned earlier, is an interpreted language. An interpreter is a program that executes other programs, and when you are doing Python programming, the Python interpreter reads your program and carries out the instructions it contains.

In its simplest form, a python program is just a text file containing Python statements. For example, the initial “Hello, world” program from the previous article is a very simple Python script, but it passes for a fully functional Python program:

print(‘Hello, world!’)

This program contains a single Python print statement, which simply prints a string to the output stream, and thus is a very simple example of Python programming. We can also output the results of numeric expressions if we want:

print(3+5)

This will print an “8” to the output stream.

Python Programming: Running Python Programs

Perhaps the easiest way to begin Python programming is to type in programs at Python’s interactive command line. There are many ways to do this: start it in an IDE, from a system console, and so on. Assuming that Python is installed on your system (we covered installation in a previous article), the simplest and most platform-neutral way to start the Python interpreter is usually just to type python at your operating system’s prompt, without any other arguments. The notion of a system shell prompt is cross-platform, but how you access it varies by platform:

  • In Windows, you can type python in a DOS console window (the Command Prompt), found in the Accessories section of the Start -> Programs menu, by right mouse-clicking on the window icon on the lower left corner of the screen in Windows 8, or in the Start -> Run dialog box (run “cmd.exe”).
  • On Unix/Linux/Mac OS X, you might type this command in a shell or terminal window.
  • On handheld devices, you generally click the Python icon in the home or application window to launch an interactive session.

If you have not set your shell’s PATH environment variable to include Python’s install directory, you may need to type the full path to the Python executable on your machine (e.g. c:\Python34\python in Windows for version 3.4). The installer should update the path, however, and I have not had to type the full path under Windows or Linux. Of course, you can always use the change directory command to go to the Python install directory.

In Windows, you can also begin interactive sessions for Python programming by starting IDLE’s main window or by selecting the “Python (command line)” menu option from the Start button menu (in Windows 7 and earlier). I made a desktop shortcut for Python in Windows 8. Both the command line Python interpreter and IDLE spawn a Python interactive prompt with equivalent functionality.

When coding at the Python interactive prompt, we can type as many Python commands as we want, and each command will be run immediately after it is entered:
>>> print(‘Hello, world!’)
Hello, world!
>>> a = 3+4
>>> print(a)
7
The first command prints: Hello, world!. The second command assigns the sum of 3+4 to the variable a, and the third command prints out the value of a. Note that because the interactive session automatically prints the results of expressions you type, so you do not even need to say “print” at the prompt:
>>> a
7

We did not do much with the code in this article, but hopefully it served as an adequate introduction to Python programming, and the main point we want to remember here is that the interpreter executes the code entered on each line immediately, when the [ENTER] key is pressed. There is no need to create a source code file, and no need to run the code through a compiler and linker first, as you would do with a language such as C or C++. As we will see in future articles, you can also run multi-line statements at the interactive prompt. Such statements run immediately after you’ve enter all of its lines and pressed [ENTER] twice to add a blank line.

External Links:

The official Python site – contains many useful resources for Python programming.