[These should perhaps be placed more carefully...]
Data attributes override method attributes with the same name; to avoid accidental name conflicts, which may cause hard-to-find bugs in large programs, it is wise to use some kind of convention that minimizes the chance of conflicts, e.g., capitalize method names, prefix data attribute names with a small unique string (perhaps just an underscore), or use verbs for methods and nouns for data attributes.
Data attributes may be referenced by methods as well as by ordinary users (``clients'') of an object. In other words, classes are not usable to implement pure abstract data types. In fact, nothing in Python makes it possible to enforce data hiding — it is all based upon convention. (On the other hand, the Python implementation, written in C, can completely hide implementation details and control access to an object if necessary; this can be used by extensions to Python written in C.)
Clients should use data attributes with care — clients may mess up invariants maintained by the methods by stamping on their data attributes. Note that clients may add data attributes of their own to an instance object without affecting the validity of the methods, as long as name conflicts are avoided — again, a naming convention can save a lot of headaches here.
There is no shorthand for referencing data attributes (or other methods!) from within methods. I find that this actually increases the readability of methods: there is no chance of confusing local variables and instance variables when glancing through a method.
Conventionally, the first argument of methods is often called
self
. This is nothing more than a convention: the name
self
has absolutely no special meaning to Python. (Note,
however, that by not following the convention your code may be less
readable by other Python programmers, and it is also conceivable that
a class browser program be written which relies upon such a
convention.)
Any function object that is a class attribute defines a method for instances of that class. It is not necessary that the function definition is textually enclosed in the class definition: assigning a function object to a local variable in the class is also ok. For example:
# Function defined outside the class def f1(self, x, y): return min(x, x+y) class C: f = f1 def g(self): return 'hello world' h = g
Now f
, g
and h
are all attributes of class
C
that refer to function objects, and consequently they are all
methods of instances of C
— h
being exactly equivalent
to g
. Note that this practice usually only serves to confuse
the reader of a program.
Methods may call other methods by using method attributes of the
self
argument, e.g.:
class Bag: def empty(self): self.data = [] def add(self, x): self.data.append(x) def addtwice(self, x): self.add(x) self.add(x)
The instantiation operation (``calling'' a class object) creates an
empty object. Many classes like to create objects in a known initial
state. In early versions of Python, there was no special syntax to
enforce this (see below), but a convention was widely used:
add a method named init
to the class,
which initializes the instance (by assigning to some important data
attributes) and returns the instance itself. For example, class
Bag
above could have the following method:
def init(self): self.empty() return self
The client can then create and initialize an instance in one statement, as follows:
x = Bag().init()
In later versions of Python, a special method named __init__
may be
defined instead:
def __init__(self): self.empty()
When a class defines an __init__
method, class instantiation
automatically invokes __init__
for the newly-created class
instance. So in the Bag
example, a new and initialized instance
can be obtained by:
x = Bag()
Of course, 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 Complex: ... def __init__(self, realpart, imagpart): ... self.r = realpart ... self.i = imagpart ... >>> x = Complex(3.0,-4.5) >>> x.r, x.i (3.0, -4.5) >>>Methods may reference global names in the same way as ordinary functions. The global scope associated with a method is the module containing the class definition. (The class itself is never used as a global scope!) While one rarely encounters a good reason for using global data in a method, there are many legitimate uses of the global scope: for one thing, functions and modules imported into the global scope can be used by methods, as well as functions and classes defined in it. Usually, the class containing the method is itself defined in this global scope, and in the next section we'll find some good reasons why a method would want to reference its own class!