Python中的自定义字符串插值

Python中的自定义字符串插值,python,string,formatting,format,f-string,Python,String,Formatting,Format,F String,我想创建一个自定义f字符串。例如,始终将其格式转换为大写字母的CPT插值器: a = "World" normal_f_string = f"Hello {a}" # "Hello World" my_custom_interpolator = CPT"Hello {a}" # "Hello WORLD" 给出: Hello WORLD 我找到了答案。具体而言,以下是适用于我的问题的代码: from string import Formatter import sys def idem(x

我想创建一个自定义f字符串。例如,始终将其格式转换为大写字母的
CPT
插值器:

a = "World"
normal_f_string = f"Hello {a}" # "Hello World"
my_custom_interpolator = CPT"Hello {a}" # "Hello WORLD"
给出:

Hello WORLD
我找到了答案。具体而言,以下是适用于我的问题的代码:

from string import Formatter
import sys

def idem(x):
    return x

_conversions = {'a': ascii, 'r': repr, 's': str, 'e': idem}
# 'e' is new, for cancelling capitalization. Note that using any conversion has this effect, e is just doesn't do anything else.

def z(template, locals_=None):
    if locals_ is None:
        previous_frame = sys._getframe(1)
        previous_frame_locals = previous_frame.f_locals
        locals_ = previous_frame_locals
        # locals_ = globals()
    result = []
    parts = Formatter().parse(template)
    for part in parts:
        literal_text, field_name, format_spec, conversion = part
        if literal_text:
            result.append(literal_text)
        if not field_name:
            continue
        value = eval(field_name, locals_) #.__format__()
        if conversion:
            value = _conversions[conversion](value)
        if format_spec:
            value = format(value, format_spec)
        else:
            value = str(value)
        if not conversion:
            value = value.upper() # Here we capitalize the thing.
        result.append(value)
    res = ''.join(result)
    return res

# Usage:

a = 'World'
b = 10
z('Hello {a} --- {a:^30} --- {67+b} --- {a!r}')

为什么要这样做?@abhiarora我有一个类,它实现了shell和Python之间的桥梁。我想创建类似
sh“echo{var}”
的东西,它引用给定的变量,运行命令并返回stdout、stderr和返回代码。
from string import Formatter
import sys

def idem(x):
    return x

_conversions = {'a': ascii, 'r': repr, 's': str, 'e': idem}
# 'e' is new, for cancelling capitalization. Note that using any conversion has this effect, e is just doesn't do anything else.

def z(template, locals_=None):
    if locals_ is None:
        previous_frame = sys._getframe(1)
        previous_frame_locals = previous_frame.f_locals
        locals_ = previous_frame_locals
        # locals_ = globals()
    result = []
    parts = Formatter().parse(template)
    for part in parts:
        literal_text, field_name, format_spec, conversion = part
        if literal_text:
            result.append(literal_text)
        if not field_name:
            continue
        value = eval(field_name, locals_) #.__format__()
        if conversion:
            value = _conversions[conversion](value)
        if format_spec:
            value = format(value, format_spec)
        else:
            value = str(value)
        if not conversion:
            value = value.upper() # Here we capitalize the thing.
        result.append(value)
    res = ''.join(result)
    return res

# Usage:

a = 'World'
b = 10
z('Hello {a} --- {a:^30} --- {67+b} --- {a!r}')