[Tutor] What's in a name?

Walter Prins wprins at gmail.com
Sat Jan 4 00:48:32 CET 2014


Hi Keith,

On 3 January 2014 20:03, Keith Winston <keithwins at gmail.com> wrote:
>> So the answer to your question is just to print the string.
>> The real challenge, as we have discovered, is how to access
>> the list that is named by the string. And the usual way to
>> map strings to objects is via a dictionary not by using eval().
>
> Here's the thing: I think most of my "problems" go away with better design.
> But in case I'm wrong, what I was trying to do, which I would think could
> sometimes be helpful, is printing the name of an object along with it's
> output/results... I don't think there's any way to do the opposite of
> eval(), that is, create a string from an object name. Or am I just missing
> something here (I THINK the right way to do this is add, if necessary, and
> __name__ method, or at least a .name attribute, to the class... though now
> that I think about it I think that still doesn't solve the problem, it names
> the class not the instance.

Firstly a caveat/disclaimer/apology:  I've not read every post in this
thread in detail, so apologies if some of my comments miss the point
or has otherwise been already made to death.

Secondly, it seems to me you seem perhaps to think of an object's name
as something intrinsic, e.g. an attribute that is (or should be) part
of every object.  Note you should view objects as not having intrinsic
names unless *you* make it so via code.  The names that you associate
to your objects in your program however, are not part of your objects,
instead they live separately in namespaces and do not form part of the
objects themselves.

To belabor the point:  You should distinguish between a) references to
your objects that are "name references" that live in a namespace
somewhere (which some people call variables) and b) other anonymous
references, e.g. just non-name references held by another object (for
example such as that which is held by a list that contains your
object), and c) a potential name attribute or property you might add
to your objects to store some custom name that you'd like to give your
object at runtime (and again, which is therefore quite separate from
and distinct to any variable/namespace references that might also be
referring to your object.).

Generally, if you want an object to have a name, then make an
attribute to represent the name and use that, as you've indeed alluded
to above.  It's not usually the right idea to try and introspect back
to the (possibly many, or none) namespace references referring to your
objects.

Now, having said all that, and though I'm hesitant to even mention
this in fear of muddying the waters and confusing matters by doing so,
it is in fact possible (and with some caveats), to query for and
retrieve all the name references for an object with a bit of querying
of the Python runtime environment (specifically the garbage
collector).  Try this:

---------------
import gc, itertools

def names_of(obj):
    """Try to find the names associated to a given object."""
    #Find dict objects from the garbase collector:
    refs_dicts = (ref for ref in gc.get_referrers(obj) if isinstance(ref, dict))
    #Get a single chained generator for all the iteritems() iterators
in all the dicts
    keyvalue_pairs = itertools.chain.from_iterable(refd.iteritems()
for refd in refs_dicts)
    #Return a list of keys (names) where the value (obj) is the one
we're looking for:
    return [k for k, v in keyvalue_pairs if v is obj]

x = []
y = x
z = [x]

print names_of(z[0])
---------------

As you might expect, the last line outputs the 2 names for the list
initially named "x" above, e.g. ['x', 'y']

As for generating a string representation of an object, by convention
the output of the repr() function is usually supposed to give you a
string _repr_esentation (geddit) that should, if submitted to the
Python interpreter (or eval), give you back an equivalent object to
the one that was passed to repr().  This however is not guaranteed and
you should _NOT_ rely on repr()/eval() if you're trying to
serialise/deserialize your objects, not least due to the security
dangers implied by eval.  Instead, use the pickle module:
http://docs.python.org/2/library/pickle.html

HTH,

Walter


More information about the Tutor mailing list