11.4 Random Remarks
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. Possible conventions include
capitalizing method names, prefixing data attribute names with a small
unique string (perhaps just an underscore), or using 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:
class Bag:
def __init__(self):
self.data = []
def add(self, x):
self.data.append(x)
def addtwice(self, x):
self.add(x)
self.add(x)
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!
|