我经常发现自己使用以下模式进行字符串格式化。
a = 3
b = 'foo'
c = dict(mykey='myval')
#prints a is 3, b is foo, mykey is myval
print('a is {a}, b is {b}, mykey is {c[mykey]}'.format(**vars()))
也就是说,我经常在本地命名空间中打印需要打印的值,由对vars()的调用表示。然而,当我查看我的代码时,不断重复.format(**vars())
模式似乎非常麻烦。
我想创建一个捕获此模式的函数。它将类似于以下内容。
# doesn't work
def lfmt(s):
"""
lfmt (local format) will format the string using variables
in the caller's local namespace.
"""
return s.format(**vars())
除了当我在lfmt
命名空间时,vars()不再是我想要的。
如何编写lfmt以便它在调用者的命名空间中执行vars(),以便下面的代码可以作为上面的例子?
print(lfmt('a is {a}, b is {b}, mykey is {c[mykey]}'))
答案 0 :(得分:2)
编辑:为了让lfmt
在从不同的名称空间调用时能够正常工作,您需要inspect
模块。请注意,the documentation warns inspect
模块可能不适合生产代码,因为它可能无法与Python的所有实现一起使用
import inspect
def lfmt(s):
caller = inspect.currentframe().f_back
return s.format(**caller.f_locals)
a = 3
b = 'foo'
c = dict(mykey='myval')
print(lfmt('a is {a}, b is {b}, mykey is {c[mykey]}'))
# a is 3, b is foo, mykey is myval
答案 1 :(得分:1)
您必须检查调用帧中的变量。
这将帮助您入门:
import inspect
import pprint
def lfmt(s):
for frame in inspect.getouterframes(inspect.currentframe()):
f = frame[0]
print pprint.pformat(f.f_locals)
return '???'
if __name__ == '__main__':
a = 10
b = 20
c = 30
lfmt('test')
答案 2 :(得分:0)
你在这里:
import sys
def lfmt(s):
"""
lfmt (local format) will format the string using variables
in the caller's local namespace.
"""
if hasattr(sys, "tracebacklimit") and sys.tracebacklimit == 0:
raise Exception, "failfailfail"
try:
raise ZeroDivisionError
except ZeroDivisionError:
f = sys.exc_info()[2].tb_frame.f_back
return s.format(**f.f_locals)
a = 5
somestring = "text"
print lfmt("{a} {somestring}")
它起作用的事实并不意味着你应该使用它。这就是开发人员所说的“主要黑客”,通常附带评论“XXX修复我XXX”。
答案 3 :(得分:0)
每次调用函数时输入,vars
是否真的很糟糕?
def lfmt(s,v):
"""
lfmt (local format) will format the string using variables
from the dict returned by calling v()"""
return s.format(**v())
print(lfmt('a is {a}, b is {b}, mykey is {c[mykey]}',vars))
答案 4 :(得分:0)
您也可以使用sys
代替inspect
,但我不知道它与inspect
的实现方式是否存在相同的问题。
import sys
def lfmt(s):
caller = sys._getframe(1)
return s.format(**caller.f_locals)