- E04 - Leadership! Google, Guido van Rossum, PSF

Alex Martelli aleax at mail.comcast.net
Tue Jan 3 11:44:41 EST 2006

Duncan Booth <duncan.booth at invalid.invalid> wrote:

> Alex Martelli wrote:
> > It IS true that in Python you cannot set arbitrary attributes on
> > arbitrary objects.  The workaround is to use a dict, indexed by the id
> > of the object you want to "set arbitrary attributes on"; this has the
> > helpful consequence that separate namespaces are used, so your arbitrary
> > setting of metadata cannot interfere with the `true' attributes of the
> > object in question.
> > 
> That's a horrible suggestion (using id's, not the bit about separate 
> namespaces). If you use the id then attributes will persist beyond the
> lifetime of the object and may suddenly reappear on other unrelated objects
> later.

The second sentence is true, but does not imply the first: just add a
strong reference to the object you're imposing extra attributes on
(e.g., pile such objects into an auxiliary list).

> A better suggestion here would be to use weak references. Unfortunately,
> not every Python object can be the target of a weak reference, so there is
> a limitation here preventing a useful implementation for many builtin

...which is why I didn't suggest that;-).

> types. I can't actually think of a use case for what Ilias wants, and if
> there isn't a use case it isn't a big problem, but if anyone can come up
> with a usecase please say.

Many usecases of Lisp's property-lists might apply to Python just as
well, assuming one could associate properties/attributes to all objects
(as you can have property-lists anywhere in Lisp).

For example, you could associate to each of a lot of strings in some set
of data structures (but not necessarily all of them) the codec to be
used with that string.  This is typical metainformation: a string of
bytes as such does not tell you how to make it back into Unicode, and in
the cases where you have obtained that metainformation it would be nice
to store it somewhere (falling back to heuristics if you ever need to
deal with strings for which you haven't yet obtained the metainfo).

Similarly, some numbers (but again not necessarily all of them, for
whatever complex datastructures set they're used in) might usefully be
associated with the unit of measure they're in (again falling back to
heuristics if needed).

In Python you just know you can't easily do that so you typically turn
the whole program around to use, not strings or numbers with optional
metainfo associated to each, but instances of more complicated datatypes
which carry the information and the optional metainformation.  But if
you're used to the extremely handy idiom of just associating interesting
metainfo with any object whatsoever, that's quite a bother.

If you know that all you're decorating with propertylist is hashable,
you can use a simple dictionary -- but then one day you want to add some
metainformation to a file instance, and OUCH, that just fails... so
you're back to workarounds of various sorts, the most popular being no
doubt "superstructures" (subclasses or wrappers) holding the real data
and optional metainformation separately.

The ability of having attributes on functions is relatively recent in
Python and basically spoke to the same kind of needs (in that case,
there were also enough abuses of functions' docstrings to hold what was
in fact metainformation that nobody could really doubt the usecase for a
better approach;-).

> With the above code what would 'puts someexpressionresultingin1234.meta'
> output? i.e. is the attribute being set on all integers with the value
> 1234, or just on a specific instance of an integer.

Good question, presumably answerable with a small Ruby test (which
however I have no time to perform right now;-).


More information about the Python-list mailing list