我有一些代码可以执行大量的字符串格式化.通常,我最终得到的代码如下:
"...".format(x=x, y=y, z=z, foo=foo, ...)
Run Code Online (Sandbox Code Playgroud)
我试图将大量变量插入到一个大字符串中.
是否有充分的理由不编写这样的函数来使用inspect模块来查找要插入的变量?
import inspect
def interpolate(s):
return s.format(**inspect.currentframe().f_back.f_locals)
def generateTheString(x):
y = foo(x)
z = x + y
# more calculations go here
return interpolate("{x}, {y}, {z}")
Run Code Online (Sandbox Code Playgroud)
一种更简单,更安全的方法是下面的代码.inspect.currentframe在python的所有实现上都不可用,所以当你的代码没有时,你的代码就会中断.在jython,ironpython或pypy下它可能不可用,因为它似乎是一个cpython的东西.这使您的代码不那么便携.
print "{x}, {y}".format(**vars())
Run Code Online (Sandbox Code Playgroud)
这个技术实际上在Python教程的输入和输出章节中描述
这也可以通过将表作为关键字参数传递'**'表示法来完成.这与新的内置vars()函数结合使用时特别有用,该函数返回包含所有局部变量的字典.
也在inspect.currentframe的python文档中
CPython实现细节:此函数依赖于解释器中的Python堆栈框架支持,但不保证在Python的所有实现中都存在这种支持.如果在没有Python堆栈帧支持的实现中运行,则此函数返回None.
更新: Python 3.6具有此功能(更强大的变体)内置:
x, y, z = range(3)
print(f"{x} {y + z}")
# -> 0 3
Run Code Online (Sandbox Code Playgroud)
它[手动解决方案]导致嵌套函数有些令人惊讶的行为:
from callerscope import format
def outer():
def inner():
nonlocal a
try:
print(format("{a} {b}"))
except KeyError as e:
assert e.args[0] == 'b'
else:
assert 0
def inner_read_b():
nonlocal a
print(b) # read `b` from outer()
try:
print(format("{a} {b}"))
except KeyError as e:
assert 0
a, b = "ab"
inner()
inner_read_b()
Run Code Online (Sandbox Code Playgroud)
注意:同一个调用成功或失败取决于是否在其上方或下方提到变量.
在哪里callerscope:
import inspect
from collections import ChainMap
from string import Formatter
def format(format_string, *args, _format=Formatter().vformat, **kwargs):
caller_locals = inspect.currentframe().f_back.f_locals
return _format(format_string, args, ChainMap(kwargs, caller_locals))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1292 次 |
| 最近记录: |