[PYTHON MATRIX-SIG] Attributes vs. methods

Paul. Dubois dubois1@llnl.gov
Fri, 19 Jan 1996 11:29:04 -0800

Pardon in advance if this gets too pedantic; I figured the range of OOP
experience varies so I go somewhat slow. The question before the SIG is
whether, for example, it should be x.shape or x.shape().

First, speaking in abstract OOP terms, a class can have two kinds of
members, attributes and methods. The former is data, the latter is
executable. In some languages (but not all) you can tell which kind of
access is being made just by looking at it:
x.f   -- f is data
x.f() -- f is a method

(Aside: this is not a GoodThing. It forces the implementor of a class to
commit to a representation for f, ie. to decide once and for all how
clients will refer to f. For example, if f represents a certain
quantity, say pressure, a decision is made immediately as to whether f
is to be a primary state variable or whether to calculate it from
something else, like the temperature. It is better if a data attribute
is indistinguishable from the client's point of view from a function
that takes no arguments. Eiffel has this right.)

That said, one then has to ask whether a certain language allows 
statements of the form 

x.f = something

If it does, then maintaining the object as an abstract data type become
difficult. For example, we may have two attributes x and y and we want
to ensure a certain relationship always holds between them. Obviously,
if any old user can come along and assign something to x without
changing y, we have problems. Thus, in many languages that allow
assignment to x.f, books are written advising that all such f's be
hidden (private) and that a function x.f() be supplied to the users
instead. Then one worries about inlining, etc.

In Python, the situation is more complicated. There is no "private". So,
a convention has developed that if an attribute has a name beginning
with an underscore, then the warranty on the object is void if the
client assigns to it. This is a reasonable compromise in that the usual
strategy of having an f() and a set_f(value) may suffer some performance
penalty since inlining isn't going to be done, and anyway there is no
private data anyway.

Next, Python allows one to make it appear that f is an attribute even if
it is not, so that while x.f "works" there really isn't such a data
member and x.f = something would not be setting it (and may even fail,
depending on the way the class was written). However, learning about
this trick implies a level of sophistication beyond the level to be
expected in the user of an application in which Python is used as the
scripting language. Such a user is too likely to try to change the shape
of the matrix by assignment.

So, my conclusion is that if x.shape in the matrix class is an
attribute, and we don't want any user to do x.shape=something, we should
call it _shape, and supply an x.shape() for normal access. I think this
argument applies to the level intended for use by the general public. 
They need a simple, consistent set of rules to live by.
Paul F. Dubois, L-472				(510)-422-5426
Lawrence Livermore National Laboratory		FAX (510)-423-9969
Livermore, CA 94550				dubois1@llnl.gov
Consulting: PaulDubois@aol.com

MATRIX-SIG  - SIG on Matrix Math for Python

send messages to: matrix-sig@python.org
administrivia to: matrix-sig-request@python.org