Class Variable Access and Assignment

Steven D'Aprano steve at
Fri Nov 4 19:29:23 CET 2005

On Fri, 04 Nov 2005 04:42:54 -0800, Paul Rubin wrote:

> Steven D'Aprano <steve at> writes:
>> There are good usage cases for the current inheritance behaviour.
> Can you name one?  Any code that relies on it seems extremely dangerous to me.

Dangerous? In what way?

A basic usage case:

class Paper:
    size = A4
    def __init__(self, contents):
        # it makes no sense to have class contents,
        # so contents go straight into the instance
        self.contents = contents

To internationalise it for the US market:

Paper.size = USLetter

Now create a document using the default paper size:

mydocument = Paper("Four score and seven years ago")
print mydocument.size == USLetter
=> True

Now create a document using another paper size:

page = Paper("Eleventy MILLION dollars")
page.size = Foolscap

Because that's an instance attribute, our default doesn't change:

assert Paper().size == mydocument.size == USLetter
assert page.size != mydocument.size

In case it wasn't obvious, this is the same inheritance behaviour Python
objects exhibit for methods, except that it isn't normal practice to add
methods to instances dynamically. (It is more common to create a
subclass.) But you can do it if you wish, at least for classes you create

Objects in Python inherit behaviour from their class.
Objects in Python inherit state from their class, unless their state is
specifically stored in a per-instance basis.

Here's another usage case:

class PrintableWidget(Widget):
    prefix = "START "
    suffix = " STOP"

    def __str__(self):
        return self.prefix + Widget.__str__(self) + self.suffix

PrintableWidgets now print with a default prefix and suffix, which can be
easily changed on a per-instance basis without having to create
sub-classes for every conceivable modification:

english_gadget = PrintableWidget("data")
print english_gadget
=> prints "START data STOP"

dutch_gadget = PrintableWidget("data")
dutch_gadget.prefix = "BEGIN "
dutch_gadget.suffix = " EINDE"
print dutch_gadget
=> prints "BEGIN data EINDE"

I have to ask... did OO programming suddenly fall out of favour when my
back was turned? People still use C++, C#, Objective-C and Java, right?
Why are so many folks on this list having trouble with inheritance? Have I
missed something?


More information about the Python-list mailing list