Python:打印变量的名称和值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32000934/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 10:51:19  来源:igfitidea点击:

Python: Print a variable's name and value?

pythondebugging

提问by Mark Harrison

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= 12

How can write a function that will take a variable or name of a variable and print its name and value? I'm interested exclusively in debugging output, this won't be incorporated into production code.

如何编写一个接受变量或变量名称并打印其名称和值的函数?我只对调试输出感兴趣,这不会合并到生产代码中。

debugPrint(x)    #  or
debugPrint('x')
x=12

采纳答案by Blender

You can just use eval:

你可以只使用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):

或者更一般地(它实际上在调用函数的上下文中工作并且不会中断debug('variable'),但仅在 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

回答by Mohit Bhasi

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))

回答by Padraic Cunningham

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:

这不适用于所有版本的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.

CPython 实现细节:此函数依赖于解释器中的 Python 堆栈帧支持,不能保证在 Python 的所有实现中都存在。如果在没有 Python 堆栈框架支持的实现中运行,则此函数返回 None。

回答by Tom Hale

I wrote the following to be able to type something like (at line 41 of file describe.py):

我写了以下内容以便能够输入类似的内容(在文件的第 41 行describe.py):

describe('foo' + 'bar')
describe(numpy.zeros((2, 4)))

and see:

并看到:

describe.py@41 describe('foo' + 'bar') = str(foobar) [len=6]   
describe.py@42 describe(numpy.zeros((2, 4))) = ndarray(array([[0., 0., 0., 0.],
   [0., 0., 0., 0.]])) [shape=(2, 4)]

Here's how:

就是这样:

# Print the line and filename, function call, the class, str representation and some other info

# Inspired by https://stackoverflow.com/a/8856387/5353461
import inspect
import re


def describe(arg):
    frame = inspect.currentframe()
    callerframeinfo = inspect.getframeinfo(frame.f_back)
    try:
        context = inspect.getframeinfo(frame.f_back).code_context
        caller_lines = ''.join([line.strip() for line in context])
        m = re.search(r'describe\s*\((.+?)\)$', caller_lines)
        if m:
            caller_lines = m.group(1)
            position = str(callerframeinfo.filename) + "@" + str(callerframeinfo.lineno)

            # Add additional info such as array shape or string length
            additional = ''
            if hasattr(arg, "shape"):
                additional += "[shape={}]".format(arg.shape)
            elif hasattr(arg, "__len__"):  # shape includes length information
                additional += "[len={}]".format(len(arg))

            # Use str() representation if it is printable
            str_arg = str(arg)
            str_arg = str_arg if str_arg.isprintable() else repr(arg)

            print(position, "describe(" + caller_lines + ") = ", end='')
            print(arg.__class__.__name__ + "(" + str_arg + ")", additional)
        else:
            print("Describe: couldn't find caller context")

    finally:
        del frame
        del callerframeinfo

https://gist.github.com/HaleTom/125f0c0b0a1fb4fbf4311e6aa763844b

https://gist.github.com/HaleTom/125f0c0b0a1fb4fbf4311e6aa763844b

回答by Sujay Kumar

A simple example would be:

一个简单的例子是:

def debugPrint(*expr):
    text = traceback.extract_stack()[-2][3]
    begin = text.find('debugPrint(') + len('debugPrint(')
    end = text.find(')',begin)
    text=[name.strip() for name in text[begin:end].split(',')]
    for t, e in text, expr:
        print(str(t) +  " = " + str(e))

Hope it helps!

希望能帮助到你!

回答by ivan_pozdeev

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.)

(我在名称之前使用了一个空行,在值 'cuz 之前使用了一个换行符,因为在我的情况下,我需要打印大型数据结构。使用换行符更容易阅读这样的输出。)

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

只要您不传递不受信任的输入,它就是安全的。

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

您可能也对我的dump模块感兴趣。它以人类可读的形式打印所有对象的字段。证明对调试非常有用。

回答by chikitin

Taking response @Blender response one step further with multiple variables:

使用多个变量进一步响应@Blender 响应:

def debug(variables, sep =''):
        vars = variables.split(',')
        for var in vars:
          print(var, '=', repr(eval(var)), end = sep)

Example:

例子:

import bumpy as np
gPrimeLinear = lambda z: np.ones(np.array(z).size)*z
gPrimeSigmoid = lambda z: 1./(1+np.exp(-z))*(1-1./(1+np.exp(-z)))
gPrimeTanh = lambda z: 1- np.tanh(z)**2
z = np.array([ 0.2, 0.4, 0.1])
debug("z, gPrimeLinear(z), gPrimeSigmoid(z), gPrimeTanh(z)", '\n')

This returns:

这将返回:

> z = array([0.2, 0.4, 0.1])  
> gPrimeLinear(z) = array([0.2, 0.4, 0.1]) 
> gPrimeSigmoid(z) = array([0.24751657, 0.24026075, 0.24937604]) 
> gPrimeTanh(z) = array([0.96104298, 0.85563879, 0.99006629])