[Python-ideas] Shorthand syntax for get/set/delattr (was Re: Dict-like object with property access)

Nick Coghlan ncoghlan at gmail.com
Sun Feb 5 01:20:30 CET 2012


Rather than throwing out random ideas in a popularity contest, it's
important to carefully review what it is that people don't like about
the current state of affairs.

Currently, when dealing with attributes that are statically
determined, your code looks like this:

    x.attr  # Reference
    x.attr = y  # Bind
    del x.attr  # Unbind

Now, suppose for some reason we want to determine the attributes
*dynamically*. The reason for doing this could be as simple as wanting
to avoid code duplication when performing the same operation on
multiple attributes (i.e. "for attr in 'attr1 attr2 attr3'.split():
...").

At this point, dedicated syntactic support disappears and we're now
using builtin functions instead:

    getattr(x, attr)  # Reference
    setattr(x, attr, y)  # Bind
    delattr(x, attr)  # Unbind
    hasattr(x, attr) # Existence query (essentially a shorthand for
getattr() in a try/except block)

So, that's the status quo any proposals are competing against. It's
easy enough to write, easy to read and easy to look up if you don't
already know what it does (an often underestimated advantage of
builtin operations over syntax is that the former are generally *much*
easier to look up in the documentation).

However, it can start to look rather clumsy when multiple dynamic
attribute operations are chained together.

Compare this static code:

    x.attr1 = y.attr1
    x.attr2 = y.attr2
    x.attr3 = y.attr3

With the following dynamic code:

    for attr in "attr1 attr2 attr3".split():
        setattr(x, attr, getattr(y, attr))

The inner assignment in that loop is *very* noisy for a simple
assignment. Splitting out a temporary variable cleans things up a bit,
but it's still fairly untidy:

    for attr in "attr1 attr2 attr3".split():
        val = getattr(y, attr)
        setattr(x, attr, val)

It would be a *lot* cleaner if we could just use a normal assignment
statement instead of builtin functions to perform the name binding. As
it turns out, for ordinary instances, we can already do exactly that:

    for attr in "attr1 attr2 attr3".split():
        vars(x)[attr] = vars(y)[attr]

In short, I think proposals for dedicated syntax for dynamic attribute
access are misguided - instead, such efforts should go into enhancing
vars() to return objects that support *full* dict-style access to the
underlying object's attribute namespace (with descriptor protocol
support and all).

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-ideas mailing list