Python:一种避免&lt; <print“variable_name =”,variable_name&gt;&gt;?

时间:2015-11-20 23:27:32

标签: python printing namespaces

&lt; p&gt;我经常写&lt; / p&gt; &lt; pre&gt;&lt; code&gt; print“variable_name =”,variable_name &LT; /代码&GT;&LT; /预&GT; &lt; p&gt;在我的python脚本中,并且更喜欢这样的内容:&lt; / p&gt; &LT;预&GT;&LT;代码&GT; name_print(变量名) &LT; /代码&GT;&LT; /预&GT; &lt; p&gt;具有相同的功能,以节省打字。&lt; / p&gt; &lt; p&gt;任何人都有任何建议吗?&lt; / p&gt; &lt; p&gt;这是一个重复的: &lt; a href =“https:=”“stackoverflow.com =”“questions =”“592746 =”“你怎么打印一个变量名在-python”=“”>你怎么能在python中打印一个变量名?

但是这个问题得到了很多,而且你做错了#34;类型的答案。 我认为我的申请非常合理,而且必须是某人遇到并解决的问题....

4 个答案:

答案 0 :(得分:2)

尝试实现name_print(variable_name)之类的问题时,您将遇到的问题是,在调用函数时,只传递其值。函数在任何可能具有相关性的范围内都不知道变量的名称。所以你必须将名称作为字符串传递,然后从调用者的框架对象中挖掘出值:

from inspect import currentframe

def name_print(name):
    frame = currentframe().f_back
    locs, globs = frame.f_locals, frame.f_globals
    value = locs[name] if name in locs else globs.get(name, "???")
    print name, "=", value
    del frame

 n = 42
 name_print("n")

您可以添加其他功能,例如属性查找(例如start.line),甚至是完整评估,但我会将其作为练习。

将名称传递给函数而不必将其放在引号中的唯一方法是在对象上使用__getattr__。所以你可以写这样的东西,但是为了避免使用字符串,这将是非常不寻常的语法。

from inspect import currentframe

class NamePrint(object):

    def __getattribute__(self, name):
        frame = currentframe().f_back
        locs, globs = frame.f_locals, frame.f_globals
        value = locs[name] if name in locs else globs.get(name, "???")
        print name, "=", value
        del frame

n = 42
name_print = NamePrint()
name_print.n

答案 1 :(得分:0)

在考虑周末之后,我想出了一个更好的答案,允许你传递变量,而不必先将变量名称串起来。

def print_variable(variable):
    import inspect
    import re

    frame = inspect.currentframe()
    this_f_name = inspect.getframeinfo(frame).function
    var_name = re.search(r"{}\((\w+)\)".format(this_f_name), inspect.getframeinfo(frame.f_back).code_context[0]).group(1)

    print "{} - {}".format(var_name, variable)

    del frame


def main():
    apples = 100
    print_variable(apples)


if __name__ == '__main__':
    main()

这使用内省来计算 print_variable 函数的名称,然后检查调用上下文的源代码,并在调用函数时在括号之间提取内容。 / p>

答案 2 :(得分:-1)

以下是使用dictlocals()词典的版本:

def print_dict(d):
    for k,v in d.items():
        print k, '=', v

print_dict(locals())

答案 3 :(得分:-1)

正如R Nar所说,有方法,希望这会对你有所帮助。您可以使用inspect模块来查询引用框架和应用程序的调用堆栈。我没有对此代码进行压力测试,因此无法保证您将使用它的跑道数量。希望够了!我可以肯定的是,根据您的特定Python实现,inspect.currentframe()可能不可用。我已经在标准的CPython 2.7.10上测试了这个。

您需要创建一个可在您需要的地方访问的功能:

def print_variable(variable_name):
    import inspect
    frame = inspect.currentframe()
    try:
        value = frame.f_back.f_locals[variable_name]
        print variable_name, "-", value
    except KeyError:
        print variable_name, "does not exist!"
    finally:
        del frame

使用frame和frame.f_back可以检查调用函数的框架(当然很危险!)并使用f_locals从该框架的本地中获取变量的值。

作为侧边栏,由于 del frame 背后的原因是防止循环引用计数会阻止垃圾收集器删除帧对象。如果您对此感兴趣,请查看here

此函数将依赖于传递要打印的变量,方法是传递其名称的字符串。这会让你到达你需要的地方,或者你是否希望能够自己传递变量(而不是字符串)?

>>> my_var = '123'
>>> print_variable('my_var')
'123'