Classes & Instances

Cesar Douady cesar.douady at asim.lip6.fr
Thu Jan 10 09:34:34 EST 2002


I actually have the same problem in my application (I am actually trying to
represent some various pieces of information with a Python program).
My conclusion is that the right way to do it is to overload the globals()
or locals() dictionary, such as :

class NamingDict(dict):
	def __setitem__(self,key,val):
		try:
			val.name=key
		except: pass
		dict.__setitem__(self,key,val)

class Foo: pass

d=NamingDict({"a":Foo()})
exec "b=a;print 'a has name :','name' in dir(a)" in d,None

but it prints : "a has name : 0" instead of  "a has name : 1"

I cannot retrieve the reference, but I understood that this feature was
considered normal by Guido, although he has optimization problems for
local accesses.

The current situation is that this works neither with locals nor globals,
and the reason is that the Python interpreter directly calls the dict
method, even if the globals() dict has overridden methods (for locals, it
is even more optimized).

I have a very simple patch to the interpreter to make things work with
globals (no measurable performance impact)
and the situation is significantly more complex for locals but I
think I can come to an implementation in which performance is not
degraded in the normal case (i.e. when locals() is a plain dict) and in
which the full semantic of exec and eval is ensured.

Because I think that people needing this feature are the exceptions more
than the rule, I do not expect anyone to actually update the interpreter.

My question now is : how do I propose a patched interpreter so that it
becomes (if accepted, of course) integrated in a future release (note that
this is more a bug fix than a new feature) ?

Note also that you cannot set the local dictionary of a function call
through exec. For example :

def foo():
	try:
		print "x = %s"%x
	except:
		print "x is not set"
	x=0 # make x a local variable

exec foo.func_code in {"x":1} # set both locals and globals

outputs : "x is not set" instead of "x = 1"

This also should be fixed and I am prepared to do the work as well.

In article <a11mre$srm$1 at serv1.iunet.it>, "Alex Martelli" <aleax at aleax.it>
wrote:

> "Mark McEahern" <marklists at mceahern.com> wrote in message
> news:mailman.1010000166.31356.python-list at python.org...
>> original post essentially asked:
>>
>> how do I get an instance's name?
>>
>> pseudocode:
>>
>>   class A:
>>     def instanceName(self):pass
>>
>>   f = a()
>>
>>   print f.instanceName # should print "f"
>>
>> a tangential suggestion might be to look into implementing one of the
>> creational patterns from GoF in Python to control the creation of class
>> instances, thereby allowing you to keep track of them.
> 
> You need no such complication to "keep track of" a class's instances --
> it's easy and idiomatic to do it e.g. by appending a reference (I'd
> suggest a weakref) to a per-class list in the instance's __init__, for
> example.
> 
> This has nothing to do with *NAMES*, and the fact that the original
> poster's request, properly translated into "how do I get the name to
> which, in the future, the instance that is being created right now will
> be bound" has no Python solution.  First of all, Guido would have to
> insert in Python his beloved time machine, because, as the instance is
> being created, no name yet is bound to it.  Even that would not make
> things SIMPLE -- what "name" should be returned in the case of
>     somelistorother.append(a())
> or
>     x=y=z=t=a()
> or
>     f(a(),a(),a(),a())
> or...?!
> 
> The only solution is apparently an exhaustive search, AFTER the binding
> has taken place, into all possile "names" that MIGHT now be bound to the
> generated instance (some careful definition will be needed regarding
> attributes, since of course after
>     x.y = a()
> there's no guarantee whatsoever that x.y is bound to the same object...
> maybe x.ZZZ might now be, or ...).
> 
> It's not worth it.  Maybe in some kind of debugging mode for a
> development-environment, but I have my doubts even then.
> 
> 
> Alex
> 
> 
>



More information about the Python-list mailing list