Python is an agile, dynamically typed, expressive open source programming language that can be freely installed on a variety of platforms (see Resources). Python code is interpreted. If you are more familiar with the edit, build, execute cycle, this might seem simplistic. But don't be fooled: Python programs can be simple scripts or large, complex programs. In fact, the very nature of the Python interpreter encourages exploration and simplifies the learning process. If you need proof, compose the classic Hello World! program in Python:
- Fire up the Python interpreter. (On UNIX systems, including Mac OS X, starting the interpreter usually involves typing
pythonat a command prompt; on Microsoft® Windows® systems, you can launch a Python command shell).
- At the Python prompt, denoted by three greater-than symbols (
>>>), enter print '
Hello World!' and press Enter.
- That's it: There is no third step. Listing 1 shows the output from this command.
Listing 1. Output of "Hello World" in Python
rb% python Python 2.4 (#1, Mar 29 2005, 12:05:39) [GCC 3.3 20030304 (Apple Computer, Inc. build 1495)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> print 'Hello World!' Hello World!
As you can see, I'm using Python V2.4 on an Apple OS X system. But the fundamentals are the same regardless of the operating system and, in this case, the actual version of Python you're using. I don't know about you, but this Hello World! exercise was a lot easier than the comparable exercises I did when I learned C, C++, or even the Java™ language. This simplicity demonstrates one of the primary benefits of using the Python interpreter. A developer can quickly try out an idea and explore an object's properties or different algorithms without having to compile, execute, and test any code.
The Python type hierarchy
One of the most important lessons to learn when transitioning to the Python programming language from another language is that everything in Python is an object. This might not seem unusual, especially if you're familiar with an object-oriented language, such as C++, Java, or C#. But Python's object-oriented philosophy goes beyond that of these other languages, as evidenced by two simple differences. First, all data values in Python are encapsulated in relevant object classes. Second, everything in a Python program is an object accessible from within your program, even the code you write.
Most popular programming languages have several built-in data types, and Python is no different in this respect. For example, the C programming language has integer and floating-point types. Given their lineage, it's not surprising that both the Java language and C# do, as well. This means that in a C program, you can write
int i = 100 to create and initialize an integer variable. The same is possible in the Java language and C#, and with their auto-boxing capabilities, both of those languages can turn this simple built-in type into an
Integer object when necessary.
Python, on the other hand, does not have simple types like int -- only object types. If you need an integer value in Python, you merely assign an integer value to the appropriate variable, such as
i = 100. Under the covers, Python creates an integer object and assigns the variable to reference the new object. Now comes the real kicker: Python is a dynamically typed language, so you don't have to declare a variable's type. In fact, a variable's type can actually change (multiple times) during a single program.
An easy way to visualize how the dynamic typing works is to imagine a single base class called
PyObject from which all other object types in Python inherit. In this model, any variable you create references an object that has been created from the overall class hierarchy. If you also have the
PyObject class record the actual type, or name, of the child class, which is created and assigned to the variable, a Python program can properly determine the necessary steps to take during program execution.
The mental picture presented in the previous paragraph describing Python's object-oriented model is actually a fairly good approximation of how Python actually works. In addition, Python makes it easy to determine a variable's type, using the type function. (This example also shows how to use an inline comment with the # character.)
Listing 2. Demonstrating the Python simple types
>>> i = 100 # Create an int object whose value is 100 >>> type(i) <type 'int'> >>> f = 100.0 >>> type(f) <type 'float'>
You can classify all the Python classes below the
PyObject class into four main categories that the Python run-time interpreter uses:
- Simple types -- The basic building blocks, like
- Container types -- Hold other objects
- Code types -- Encapsulate the elements of your Python program
- Internal types -- Used during program execution
By the end of this series, I will have introduced all the different categories. But in this first article, I focus on the simple types.
The simple types
Python has five simple built-in types:
complex. These types are immutable, which means that when an integer object is created, its value cannot be changed. Instead, a new simple type object is created and assigned to the variable. Using the Python
id function, you can see how the identification of the underlying
Listing 3. Using the Python
>>> i = 100 >>> id(i) 8403284 >>> i = 101 >>> id(i) 8403296
Now, this may seem like an easy way to lose objects, which would result in a memory leak. Python, like C# and the Java language, however, employs a garbage collector that frees up memory used to hold objects that are no longer referenced, like the integer object that holds 100 in the previous example.
The Boolean type
The simplest built-in type in Python is the
bool type, which can hold only one of two possible objects:
Listing 4. The
>>> b = True >>> type(b) <type 'bool'> >>> id(b) 1041552
Because there are only two possible values, the Boolean type is unique. The Python interpreter provides the only two
bool objects needed:
False. Anytime these objects are needed in a Python program, the variable just references one as appropriate. Listing 3 shows how the
bb variable has the same
id whether you assign it a value of the
b variable directly or just the
True object directly.
Listing 5. Value of the
>>> b = True >>> id(b) 1041552 >>> bb = b >>> id(bb) 1041552 >>> bb = True >>> id(bb) 1041552
The case for the name of the Boolean object is important because true (and false) is undefined:
Listing 6. Undefined true and false
>>> b = true Traceback (most recent call last): File "<stdin>", line 1, in ? NameError: name 'true' is not defined
At this point, a
bool type might not seem overly useful. However, Boolean expressions, as their name suggest, rely on them, as you see here:
Listing 7. Boolean expressions
>>> b = 100 < 101 >>> print b True
Many programs utilize Boolean expressions, and Python provides the full range of Boolean comparison and logical operations, as detailed in tables 1 and 2, respectively.
Table 1. The Boolean comparison operators in Python
|<=||less than or equal to|
|>=||greater than or equal to|
|!=||inequality (also <>)|
To be complete, the operators listed in Table 1 all have equal precedence and, unless you enclose expressions in parentheses, are applied from left to right.
Table 2. The logical operators in Python
The logical operators have lower precedence than the individual comparison operators, which makes sense because the comparison has to be evaluated before the logical operator can be evaluated. The actual precedence of the logical operators is given by the order these operators are presented in Table 2.
One interesting point about the
or and the
and logical operators in Python is that they are both shortcut operators. In simple terms, this means that given
y is evaluated only if
False. Likewise, given the expression
y is evaluated only if
True. While this functionality can improve the performance of expression evaluation -- especially for long or complex expressions -- it can also trip up programmers used to different rules learned from other languages.
The numeric types
The other four simple, built-in types in Python are all numeric types:
complex. Numeric types are common in programs, regardless of the language used. Python provides full support for arithmetic operations, including addition, subtraction, multiplication, and division (see Table 3).
Table 3. Arithmetic operators in Python
The multiplication and division operators (the first four listed in Table 3) have higher precedence than the addition and subtraction operators. And as before, you can group sub-expressions and give them higher precedence by using parentheses to set them apart.
Unlike the Java language, which formally defines the allowed range of numeric types, Python is more like C in that the range of types is platform-dependent. You use both the
long types to hold integer values, the difference being that an int is a 32-bit integer value. Thus, it is limited to holding values (on many platforms) from -232 to 232 - 1. In contrast, the long integer type has unlimited precision, subject to the memory limitations of your computer. To tell Python that an integer should be treated as a long, simply append an L to the end of the number, like 100L. Floating-point values in Python are always done in double precision; hence, Python
float types correspond to doubles in a C-like language.
Two other important points related to the numeric types are literals, which are just explicitly expressed numbers, like 100 in the previous examples, and bit operations. Programmers typically work in the decimal system (or base 10). But sometimes other systems are more useful, especially given the binary nature of computers. Python provides support for octal (base 8) and hexadecimal (base 16) numbers. To tell Python that a number should be treated as an octal numeric literal, simply append a zero to the front. Appending a zero and an x to the front of a number tells Python to treat the number as a hexadecimal numeric literal, as the following code shows:
Listing 8. Telling Python to treat the number as a hexadecimal numeric literal
>>> print 127 # Using decimal literal 127 >>> print 0177 # Using octal literal 127 >>> print 0x7F # Using hexadecimal literal 127
When you have an easy way to express numeric literals, especially in hexadecimal, you can easily build flags that correspond to specific test cases, which is a common programming trick. For example, a 32-bit integer can store 32 flag values. Using bit tests, you can easily test for specific flags on a flag variable. The complete list of bit operations in Python is presented in Table 4.
Table 4. Bit operators in Python
|<<||shift bits left|
|>>||shift bits right|
|^||bitwise exclusive or|
By now, you're probably wondering what happens when the different numerical types are mixed in a single expression. The simple answer is that Python converts all operands in an expression to the type of the most complex operand, as necessary. The complexity order is
complex (no pun intended), which is easily shown by an example:
Listing 9. Python conversion of all operands to the type of the most complex operand
>>> 1 / 3 0 >>> 1.0 / 3 0.33333333333333331 >>> 1.0 // 3 0.0 >>> 1 % 3 1 >>> 1.0 % 3 1.0
While Python will convert the operands as you might expect, the language does not convert operands based on the operator, as shown in the 1/3 example, which evaluates to an integer. If you want to force a floating-point result, be sure that at least one of the operands is a floating-point type.
The complex type
The final type,
complex, is probably not as recognizable to most programmers because it is not a common built-in data type in other programming language. To engineers and scientists, complex numbers are a familiar concept. Formally, a complex number has a real and an imaginary component, both represented by
float types in Python. An imaginary number is a multiple of the square root of minus one, which is denoted by i or j -- depending on whether you were trained as a scientist or an engineer. In Python, the imaginary component of a complex number is indicated by a j:
Listing 10. Imaginary component of a complex number
>>> c = 3.0 + 1.2j >>> print c (3+1.2j) >>> print c.real, c.imag 3.0 1.2
This example is a complex number that has a real component of 3.0 and an imaginary component of 1.2. Notice that you can access the different parts of the complex number by using the
imag attributes of the complex object.
Are they really objects?
To this point, I've told you that Python deals only with object types, yet the examples don't really seem to have any objects. After all, where are the constructors? For the simple built-in data types, Python does a lot of the work for you. But the constructors are still there -- their names are identical to the name of the relevant data type -- and if you prefer, you can use them directly, as shown below:
Listing 11. Python constructors
>>> b = bool(True) >>> i = int(100) >>> l = long(100) >>> f = float(100.1) >>> c = complex(3.0, 1.2) >>> print b, i, l, f, c True 100 100 100.1 (3+1.2j)
Python is an amazingly simple, yet powerful language. The entry barrier is extremely low, especially for a programmer who has experience with a C-like language. This article introduced the Python programming language and the built-in data types:
complex. If you haven't already done so, fire up a Python interpreter and try some of the ideas I've discussed. You'll be glad you did.
- Download Python.
- After you have a working Python interpreter, the Python tutorial is a great place to start learning the language.
- IBM developerWorks has published many articles about Python, including the advanced articles in the Charming Python column, by David Mertz.
- If you prefer to use an IDE, read Python development with Eclipse and Ant, by Ron Smith, which shows how to use Eclipse to write Python code.
- The Python Reference Manual provides a discussion of the object nature of Python.
- The Python Reference Manual also provides the legal details for integer literals and floating-point literals.
- Complex numbers aren't just for scientists and engineers. They can also be used for graphics work, such as simplifying the rotation of objects on a GUI.
- Get involved in the developerWorks community by participating in developerWorks blogs.