Python: Print a variable's name and value?

前端 未结 9 1629
一生所求
一生所求 2020-12-13 08:21

When debugging, we often see print statements like these:

print x        # easy to type, but no context
print \'x=\',x   # more context, harder to type
12
x=         


        
相关标签:
9条回答
  • 2020-12-13 08:50

    Quite ugly , but does the job :

    import inspect, re
    def getm(p):
      for line in inspect.getframeinfo(inspect.currentframe().f_back)[3]:
        match = re.search(r'\bvarname\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)\s*\)', line)
        if match:
          return match.group(1)
    x=21
    search = getm(x);
    print (search , '=' , eval(search))
    
    0 讨论(0)
  • 2020-12-13 08:51

    I've just concocted a function like this that prints an arbitrary expression:

    import inspect, pprint
    
    def pp(n):
        print()
        print(n,"=")
        f=inspect.stack()[1].frame
        pprint.pprint(eval(n,f.f_globals,f.f_locals))
    

    (I used a blank line before the name and a newline before the value 'cuz in my case, I needed to print large data structures. It's easier to read such an output with the line breaks.)

    It's safe as long as you don't pass it untrusted input.

    You might also be interested in my dump module. It prints all the object's fields in a human-readable form. Proved extremely useful for debugging.

    0 讨论(0)
  • 2020-12-13 08:56

    You can just use eval:

    def debug(variable):
        print variable, '=', repr(eval(variable))
    

    Or more generally (which actually works in the context of the calling function and doesn't break on debug('variable'), but only on CPython):

    from __future__ import print_function
    
    import sys
    
    def debug(expression):
        frame = sys._getframe(1)
    
        print(expression, '=', repr(eval(expression, frame.f_globals, frame.f_locals)))
    

    And you can do:

    >>> x = 1
    >>> debug('x + 1')
    x + 1 = 2
    
    0 讨论(0)
  • 2020-12-13 09:04

    For those who are not using python 3.8 yet, here is an alternative.

    This is a modified, shorter version of the accepted answer from a closed 2009 duplicate question found here, (which was also copied with a mistake in the below Aug 14, '15, the mistake being the re contains the hard coded function name 'varname' instead of the function name shown 'getm'). Original found here: How can you print a variable name in python??

    To explain the re below, the inspect.getframeinfo(inspect.currentframe(), f_back)[3] gives the function signature in a list

    ['                p(prev)\n']
    

    Casting to str saves you from having to loop through the list of one item. The re looks for an '(' which has to be escaped, the next '(' is to create a group within the match to reference, then [^)] means any character not ')', the '^' means 'not' in this context, brackets [] mean match any character within, and the following '*' is a quantifier for 0 or more times. Then close the group with a ')', match the closing ')' and voila:

    def p(x):
        import inspect
        import re
        m = re.search('\(([^)]*)\)',str(inspect.getframeinfo(inspect.currentframe().f_back)[3]))
        print(f' {m.group(1)}: {x}')
    

    Does this work with 2.7? Wait here while I check ... No, seemingly not. I did see one or two other variations that didn't use inspect.getframeinfo(inspect.currentframe().f_back)[3], so perhaps one of those would work. You'd have to check the duplicates and comb through the answers. Also to caution, some answers said to beware of python interpreters that may not be compatible with various solutions. The above worked on

    Python 3.6.4 (v3.6.4:d48ecebad5, Dec 18 2017, 21:07:28)
    [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin

    0 讨论(0)
  • 2020-12-13 09:05
    import inspect
    import re
    def debugPrint(x):
        frame = inspect.currentframe().f_back
        s = inspect.getframeinfo(frame).code_context[0]
        r = re.search(r"\((.*)\)", s).group(1)
        print("{} = {}".format(r,x))
    

    This won't work for all versions of python:

    inspect.currentframe()

    CPython implementation detail: This function relies on Python stack frame support in the interpreter, which isn’t guaranteed to exist in all implementations of Python. If running in an implementation without Python stack frame support this function returns None.

    0 讨论(0)
  • 2020-12-13 09:08

    Python 3.8 f-string = syntax

    It has arrived!

    #!/usr/bin/env python3
    foo = 1
    bar = 2
    print(f"{foo=} {bar=}")
    

    output:

    foo=1 bar=2 
    

    Added in commit https://github.com/python/cpython/commit/9a4135e939bc223f592045a38e0f927ba170da32 "Add f-string debugging using '='." which documents:

    f-strings now support =  for quick and easy debugging
    -----------------------------------------------------
    
    Add ``=`` specifier to f-strings. ``f'{expr=}'`` expands
    to the text of the expression, an equal sign, then the repr of the
    evaluated expression.  So::
    
      x = 3
      print(f'{x*9 + 15=}')
    
    Would print ``x*9 + 15=42``.
    

    so it also works for arbitrary expressions. Nice!

    0 讨论(0)
提交回复
热议问题