Python fully supports procedural and object-oriented programming, and leaves us free to use either approach, or to combine the two. So far we have done procedural programming, although we have already used some Python classes—for example, the str string class. What we have not yet done is defined our own classes. In this chapter we will learn how to create classes and methods, and how to do object-oriented programming with Python. And in all subsequent chapters, we will almost always use an object-oriented approach in the programs we write.
We assume that you are familiar with object-oriented programming—for example using C++ or Java—but will take the opportunity to clarify our terminology. We use the term "object", and occasionally the term "instance", to refer to an instance of a particular class. We use the terms "class", "type", and "data type", interchangeably. Variables that belong to a specific instance are called "attributes" or "instance variables". Variables that are used inside methods that are not instance variables are called "local variables", or simply "variables". We use the term "base class" to refer to a class that is inherited from; a base class may be the immediate ancestor, or may be further up the inheritance tree. Some people use the term "super class" for this concept. We use the terms "subclass" and "derived class" for a class that inherits from another class.
In Python, any method can be overridden (reimplemented) in a subclass; this is the same as Java (apart from Java's "final" methods).* Overloading, that is, having methods with the same name but with different parameter lists in the same class, is not supported, although this is not a limitation in practice because of Python's versatile argument-handling capabilities. In fact, the underlying Qt C++ API makes extensive use of overloading, but PyQt handles Qt this seamlessly behind the scenes, so in practice, we can call any "overloaded" Qt method and rely on PyQt to do the right thing.
★In C++ terminology, all Python methods are virtual.
This chapter begins with the basic syntax for creating classes. We then look at how to construct and initialize objects, and how to implement methods. One of the nicest features of Python's object-oriented support is that it allows us to reimplement "special methods". This means we can make our classes seamlessly blend in so that they behave just like built-in classes. For example, it is easy to make our classes work with the comparison operators such as == and <. We then look at the numeric special methods: these allow us to overload operators such as + and += which can be useful when creating complete custom data types, especially numeric ones. If our class is a collection, there are some additional special methods we can reimplement so that, for example, our collection will support the in operator and the len() function. The chapter concludes with a section on Python's support for inheritance and polymorphism.
For historical reasons, there are two kinds of user-defined types (classes) that Python provides: "old-style" and "new-style". The only obvious difference is that old-style classes either have no base class, or have only old-style base classes. New-style classes always derive from a new-style class, for example, object, Python's ultimate base class. Since there is no reason to use old-style classes, and because they will be dropped from the language from Python 3.0, we will always use new-style classes.
The syntax for creating a class is simple:
class className(baseclasses): suite
In the class's suite we can have def statements; and in such a context they create methods for their enclosing class rather than functions.
It is also possible to have "empty" classes, with no methods or attributes (data members) of their own, as we saw at the end of the preceding chapter when we derived our own custom exception class.
New-style classes always have at least one base class—for example, object. Unlike Java, Python supports multiple inheritance, that is, Python classes can inherit from one, two, or more base classes. We will mostly avoid this feature because it can lead to unnecessary and confusing complexity. Python does not support abstract classes (classes that cannot be instantiated, and that can only be derived from—useful for defining interfaces), but the effect of having an abstract class can be achieved all the same. We will look at a small example of multiple inheritance where one of the base classes is "abstract" and is used purely to provide an API (rather like a Java interface).
In Python, all methods and attributes are accessible from both inside and outside the class; there are no access specifiers such as "public" and "private". Python does have a concept of "private"—objects with names that begin with a single leading underscore are considered to be private. As far as methods and instance variables are concerned, their privacy is merely a convention that we are invited to respect. And as for modules, private classes and functions, that is, those whose name begins with a leading underscore, are not imported when using the from moduleName import * syntax. Python also has a concept of "very private"—methods and attributes with names that begin with two leading underscores. Very private objects are still accessible, but the Python interpreter mangles their names to make it difficult to access them by mistake.
Now that we know the basic syntax for creating a class and have a broad overview of Python's object-oriented features, we are ready to see how to create a class and some instances.
Was this article helpful?
Discover How You Can Quickly And Easily Dominate Google and YouTube... With Simple Cash Generating Videos. Did you know that YouTube is the second largest search website on the entire Internet? YouTube gets more daily searches than Bing and Yahoo. In fact, there is only one search engine that gets more action.