[Tutor] introspection

Peter Otten __peter__ at web.de
Mon Apr 20 19:34:27 CEST 2015


Alex Kleider wrote:

> On 2015-04-20 09:15, Joel Goldstick wrote:
>> On Mon, Apr 20, 2015 at 11:24 AM, Alex Kleider <akleider at sonic.net>
>> wrote:
>>> Does python provide the introspective ability to retrieve the name to
>>> which
>>> an object is bound?
>>> 
>>> For example:
>>> $ python3
>>> Python 3.4.0 (default, Apr 11 2014, 13:05:18)
>>> [GCC 4.8.2] on linux
>>> Type "help", "copyright", "credits" or "license" for more information.
>>>>>> 
>>>>>> a = 69
>>>>>> print("Identifier <{}> is bound to {}.".format(a.__name__, a))
>>> 
>>> Traceback (most recent call last):
>>>   File "<stdin>", line 1, in <module>
>>> AttributeError: 'int' object has no attribute '__name__'
>>> 
>>> 
>> An object can be bound to multiple names.  Within a namespace you can
>> use locals to see names, then compare various names like so:
>>> 
>>>>> a = 3
>>>>> b = 6
>>>>> c = a
>>>>> locals()
>> {'a': 3, 'c': 3, 'b': 6, '__builtins__': <module '__builtin__'
>> (built-in)>, '__package__': None, '__name__': '__main__', '__doc__':
>> None}
>>>>> a is b
>> False
>>>>> a is c
>> True
> 
> Showing my desired use case might make my question more understandable:
> def debug(var_name):
>      if args["--debug"]:
>          print("Identifier <{}> is bound to: {}"
>              .format(var_name.__name__, repr(var_name)))
> I don't think the built in locals() can help me.
> Thanks all the same.
> Alex

In CPython you can inspect the callstack, but remember that 

(1) it is a costly operation
(2) there are many variables bound to multiple names or none at all.

$ cat show_name_binding2.py 
import sys

def bindings_of(value, depth):
    frame = sys._getframe(depth + 1)
    bindings = [n for n, v in frame.f_locals.items() if v is value]
    if bindings:
        return bindings
    return ["<no bindings found>"]

def debug(value):
    print("{} is bound to {}".format(
        value, ", ".join(bindings_of(value, 1))))

def main():
    x = 42
    y = 42
    
    debug(42)
    debug("foo")
    
    a = "bar baz"
    b = " ".join(a.split())
    assert a == b
    debug("bar baz")

if __name__ == "__main__":
    main()
$ python3 show_name_binding2.py 
42 is bound to y, x
foo is bound to <no bindings found>
bar baz is bound to a




More information about the Tutor mailing list