Running code on assignment/binding

Michael Spencer mahs at telcopartners.com
Tue Jun 20 18:48:24 EDT 2006


David Hirschfield wrote:
> Another deep python question...is it possible to have code run whenever 
> a particular object is assigned to a variable (bound to a variable)?
> 
> So, for example, I want the string "assignment made" to print out 
> whenever my class "Test" is assigned to a variable:
> 
> class Test:
>   ...
> 
> x = Test
> 
> would print:
> 
> "assignment made"
> 
> Note that there's no "()" after x = Test, I'm not actually instantiating 
> Test, just binding the class to the variable "x"
> Make sense? Possible?
> -David
> 
Not in general (you can't "override" assignment), but here are some possible 
workarounds for special cases:

1. If this is for some interactive use, you could call gc.get_referrers each 
time round the REPL to see how many names have been bound to each object you 
care about.

2. Alternatively, you could exec your code in an instance of a dict subclass 
that overrides setitem.

 >>> class chatty_dict(dict):
...     def __setitem__(self, k, v):
...         print "Binding %s to %r" % (k, v)
...         dict.__setitem__(self, k, v)
...
 >>> d= chatty_dict()
 >>> source = """
... class Test: pass
... a = Test"""
 >>>
 >>> exec source in d
Binding Test to <class __builtin__.Test at 0x01CFCAE0>
Binding a to <class __builtin__.Test at 0x01CFCAE0>
 >>>

(With a little more work, you can make a chatty_dict that wraps the __dict__ of 
a loaded module)

3. Limit yourself to attribute assignment, which can be overridden:

 >>> SomeInstance.a = Test

Then you can use __setattr__ or a data descriptor to customize the assignment

HTH
Michael




More information about the Python-list mailing list