我通常使用以下模式(如this question中所述):
a=1
s= "{a}".format(**locals())
我认为这是编写易读代码的好方法。
有时“链接”字符串格式是有用的,以便“模块化”复杂字符串的创建:
a="1"
b="2"
c="{a}+{b}".format(**locals())
d="{c} is a sum".format(**locals())
#d=="1+2 is a sum"
很快,代码就会被X.format(**locals())
纠缠不清。
为了解决这个问题,我尝试创建一个lambda:
f= lambda x: x.format(**locals())
a="1"
b="2"
c= f("{a}+{b}")
d= f("{c} is a sum")
但这会引发KeyError,因为locals()
是lambda的本地人。
我还尝试仅在最后一个字符串上应用格式:
a="1"
b="2"
c="{a}+{b}"
d="{c} is a sum".format(**locals())
#d=="{a}+{b} is a sum"
但这不起作用,因为python只格式化一次。 现在,我可以编写一个重复格式化的函数,直到没有其他事情要做:
def my_format( string, vars ):
f= string.format(**vars)
return f if f==string else my_format(f, vars)
但我想知道:有更好的方法吗?
答案 0 :(得分:4)
f = lambda x, l=locals(): x.format(**l)
似乎有用......
如果你想要一个更全面的版本(并且可能慢很多):
fg = lambda x, l=locals(), g=globals(): x.format(**dict(g.items() + l.items()))
将在本地或全局中找到符号。
答案 1 :(得分:2)
如果您只需要在功能范围内以本地快捷方式执行此操作,则以下内容将起作用:
def formatter(fmt, loc=locals()):
return fmt.format(**loc)
但是,这将在函数声明时绑定locals()
返回的值,而不是执行,因此它不会随着值的更改而更新,也不会在从任何其他范围调用时有用。
如果您想要访问调用方法的locals
,则需要inspect
调用堆栈(http://docs.python.org/2/library/inspect.html)
import inspect
def formatter(fmt):
parent = inspect.stack()[1][0] # 1 = the previous frame context
# 0 = the frame object
return fmt.format(**parent.f_locals)
请注意,这可能不适用于不是CPython的python实现。
现在你可以做到:
a = "1"
b = "2"
c = formatter("{a}+{b}")
d = formatter("{c} is a sum")
答案 2 :(得分:1)
从Python 3.6开始,**locals()
的效果已经包含在string#format
中,或者更确切地说是“格式化的字符串文字”。
答案 3 :(得分:0)
这不是单行,但它有效:
def fmt(s, l=locals()):
while '{' in s:
s = s.format(**l)
return s
a="1"
b="2"
c="{a}+{b}"
d="{c} is a sum"
print fmt(d) # 1+2 is a sum
这是一行(效率稍低)的递归版本:
fmt = lambda s, l=locals(): fmt(s.format(**l), l=l) if '{' in s else s