Constructions

Python, like all languages, gives you constructions for looping, branching and jumping. In addition, since Python 2.2, you can also use iterators and generators.

Looping

You do not use counters to loop in Python. Rather, you use sequences of objects to loop over. Those objects can of course also be be numbers, generated by either range or xrange:

Python 2.1.1 (#1, Aug 11 2001, 20:14:53)
[GCC 2.95.2 19991024 (release)] on linux2
Type "copyright", "credits" or "license" for more information.
>>> aList=["a","b","c"]
>>> for item in aList:
...     print item
...
a
b
c
>>> for counter in range(3):
...     print counter
...
0
1
2
>>>
      

Another loop repeats a block of statements while a certain expression evaluates to true:

>>> a=0
>>> while a < 3:
...     print a
...     a+=1
...
0
1
2
      

The break statement breaks execution out of a loop; the continue statement continues immediately with the next iteration.

Iterators define a __iter__ and a next() function to allow easy looping:

# iter.py - an iterator

class MyIterator:

    def __init__(self, start):
        self.start = start

    def __iter__(self):
        return self

    def next(self):
        if self.start < 10:
            self.start += 1
            return self.start
        else:
            raise StopIteration


for i in MyIterator(1):
    print i
      

Generators are functions that return a function that can yield a result part-way compution, and resume later:

# generator.py

from __future__ import generators

def MyGenerator():
    count = 0
    while count < 10:
        yield count
        count += 1

gen = MyGenerator()
try:
    while 1:
        print gen.next()
except StopIteration:
    print "finished"
      

Note how yield returns the number, but count is still increased.

Branching

The number zero, empty lists, dictionaries, tuples and the object None all evaluate to false; (almost) everything else is true. You create branches using the if statement.

>>> a=1
>>> if a:
...     print "true"
... else:
...     print "false"
...
true
>>> if a==0:
...     print "a was zero"
... elif a == None:
...     print "a was none"
... else:
...     print "a was zero nor none"
...
a was zero nor none
      

The operator == tests for equality, while != (or the deprecated <>) tests for inequality. The operator is tests for identity: that is, whether two references point to (unless you import division from future in Python 2.2) the same object:

>>> from qt import *
>>> a=QString("bla")
>>> b=QString("bla")
>>> a is b
0
>>> c=a
>>> a is c
1
>>> a="bla"
>>> b="bla"
>>> a is b
1
>>> id(a)
135455928
>>> id(b)
135455928
      

As you can see, Python does some optimizations that reuse the same string object if the string contents are the same.

Exceptions

As every modern programming language must have, Python contains an error catching construction. This is the try: ... except... construction.

>>> try:
...     1/0
... except ZeroDivisionError:
...     print "Zerodivisionerror"
...
Zerodivisionerror
      

You can also create your own exceptions that can carry significant data about the causes of the error:

>>> class BlaError:
...     def __init__(self, value):
...             self.value = value
...     def __str__(self):
...             return repr(self.value)
>>> try:
...     raise BlaError("Bla happened - that's bad!")
... except BlaError, error:
...     print error
...
Bla happened - that's bad!
      

If you want to catch several different exceptions, you have to create a tuple of all the exceptions you want to catch:

>>> try:
...     print "bla"
... except (ValueError, ZeroDivisionError):
...     print "that's bad"
... 
bla
      

Finally, you can define something that should happen when all errors have been handled in the finally block:

>>> try:
...     1/0
... finally:
...     print "finally"
...
finally
Traceback (most recent call last):
  File "<stdin>", line 2, in ?
ZeroDivisionError: integer division or modulo by zero
      

Classes

Classes are defined with the class keyword. Python classes can inherit from zero, one, or more other classes, but from only one PyQt class.

Classes are initialized using the code in the __init__ method. There are other special methods, like __str__, which should return a string representation of the class. Consult the Python language reference for a complete list of these.

>>>class A:pass
...
>>> class B(A):
...     def __init__(self, val):
...             self.val = val
...     def __str__(self):
...             return str(self.val)
...
>>> b=B(10)
>>> print b
10
>>>