Instance of class "object"

Hrvoje Niksic hniksic at xemacs.org
Fri May 16 05:16:34 EDT 2008


"甜瓜" <littlesweetmelon at gmail.com> writes:

> Howdy,
>     I wonder why below does not work.
>
> a = object()
> a.b = 1        # dynamic bind attribute failed...

Because the default object class doesn't have a dict or other
indication of state.  It's a "pure" Python object whose only visible
properties are its type and its identity.  (On the implementation
level it also has a refcount.)

This is necessary because all other Python objects (both new-style
classes and C extensions) inherit from 'object', on the C level.
Having state in 'object' would mean having that same in *all* other
Python objects.  The current design, on the other hand, allows
creation of very lightweight python objects that don't even have a
dict.

Subclassing object instructs Python as to what kind of state you want
your class to have.  The default is to have a dict to store
properties:

# a class with dict -- any property goes through dict, and creating a
# Foo object actually creates two objects, one Foo and one dict
class Foo(object):
    pass

But you can also specify:

# an efficient 'Pair' class holding two objects
class Pair(object):
    __slots__ = 'first', 'second'

Instances of Pair take up even less room that 2-element tuples
because they don't carry the size information in the object.

Now, if the object class carried a dict with it, it would be
impossible to create a class like 'Pair'.

> To make it correct, we have to create a new class:
> class MyClass(object): pass
> a = MyClass()
> a.b = 1       # OK
>
> Does this strange behavior break the LSP (Liskov substitution
> principle)?

It follows from LSP that what the subclass may not introduce new
preconditions.  In this case the subclass accepts a case that the
original class didn't, so it doesn't introduce a new precondition, it
simply weakens (removes) an existing one.



More information about the Python-list mailing list