[Python-ideas] objects aware of being bound to a name

Eric Snow ericsnowcurrently at gmail.com
Sat Jun 4 08:11:31 CEST 2011


When a name is bound to an object, the object doesn't hear about it,
usually.  The exceptions I could
think of are class and function definitions, and imports.  Also, you
can sneak around it using
setattr/descriptors if you control the class...  However, objects are
otherwise (and generally) blind to
their names.

This is relevant when you want an object to be aware of the contexts
in which it exists.  It also relates
to DRY issues that people bring up sometimes with regards to
descriptors and namedtuple (though
I'm not sure its that big a deal).

Here are three approaches that satisfy this situation:

1. have assignment automatically pass the name to the __init__ when
binding a new instance.

2. bind the name to __name__ on the object before calling __init__.

3. call __bound__(self, name, obj) on the object before __init__ is
called (or maybe after).

The first is the approach import/class/def take.  You can't really
generalize that, though, since most
classes don't have a name parameter.  Both the first and second
approach only work when the object
to be bound is instantiated.  The second seems to work better than the
first, but __name__ shouldn't
be re-bound on an object every time it is involved in an assignment.
It might be a good special-case,
though.

I like the third option because it could be tried for any name
binding, from assignment to function
arguments.  However, that may be its downfall too.  I would guess that
name binding happens more
than just once or twice during the course of execution <wink>.  I
would also guess that it would kill
performance.  However, I don't know the ins and outs of the
compiler/runtime so I could be pleasantly
wrong.

In addition to __bound__, an __unbound__ could be leveraged (wait for
it) to let an object know when
it has been unbound from a name (during del or when another object is
bound to the name).  Of course
you get double the performance hit from just __bound__.

Like most things, this can already be done, just not cleanly.  Here's
an example of more or less
equivalent code:

    class Something:
        def __init__(self):
            self._names = set()
        def __bound__(self, name, obj):
            if (name, obj) in set:
                return
            self._names.add((name, obj))
        def __unbound__(self, name, obj):
            self._names.remove((name, obj))

    obj = __import__(__file__.rsplit(".py", 1)[0])

    something = Something()
    something.__bound__("something", obj)

    something.__unbound__("something", obj)
    something = Something()
    something.__bound__("something", obj)

    something.__unbound__("something", obj)
    del something


So you can do it already, explicitly, but it's a mess.  I wouldn't be
surprised if there was a way to
be smarter about when to call __bound__/__unbound__ to alleviate the
performance hit, but I don't
see it.  I also wouldn't be surprised if there was a trivial way to do
this, or if no one's brought it up
because it's such an obviously bad idea! :)  Maybe I just need to get
go some sleep.

Regardless, this idea hit me suddenly while I was working on something
else.  I don't remember
what prompted the idea, but I at least wanted to float it out there.
Even if it's a terrible idea, I think
the concept of letting the bound object know how it's bound is an
interesting one.  It's an angle I
had not considered before.

Thanks,

-eric



More information about the Python-ideas mailing list