Python fstring as function

I would like to use f-string Python for its syntactic simplicity compared to string.Template () or another approach. However, in my application, a string is loaded from a file, and variable values ​​can be provided later.

If there is a way to call the fstring function separately from the string definition? Hope the code below explains better what I hope to achieve.

a = 5
s1 = f'a is {a}' # prints 'a is 5'

a = 5
s2 = 'a is {a}'
func(s2) # what should be func equivalent to fstring
+5
source share
6 answers

Use str.format().

Preferably, I explicitly pass arguments to him. But as a stop measure, you can use locals()to pass the specification of local (functional) variables to the formatting function:

foo = 'bar'
print('Foo is actually {foo}'.format(**locals()))

, , globals() dict locals() f-string.

+2

. a .

dictionary = {
  'a':[5,10,15]
}

def func(d):
  for i in range(3):
      print('a is {{a[{0}]}}'.format(i).format_map(d))

func(dictionary)

a is 5
a is 10
a is 15
+1

:

pip install fstring

from fstring import fstring

x = 1

y = 2.0

plus_result = "3.0"

print fstring("{x}+{y}={plus_result}")

# Prints: 1+2.0=3.0
+1

:

In [58]: from functools import partial

In [59]: def func(var_name, a):
    ...:     return var_name + f' is {a}'
    ...:

In [60]: f = partial(func, 'a')

In [61]: f(5)
Out[61]: 'a is 5'
0

eval() locals(), locals, f- .

def fstr(fstring_text, locals, globals=None):
    """
    Dynamically evaluate the provided fstring_text
    """
    locals = locals or {}
    globals = globals or {}
    ret_val = eval(f'f"{fstring_text}"', locals, globals)
    return ret_val

:

format_str = "{i}*{i}={i*i}"
i = 2
fstr(format_str, locals()) # "2*2=4"
i = 4
fstr(format_str, locals()) # "4*4=16"
fstr(format_str, {"i": 12}) # "10*10=100"
0

re.sub :

def f(string):
    frame = inspect.currentframe()
    g = frame.f_back.f_globals
    l = frame.f_back.f_locals
    try:
        repl = lambda m: str(eval(m.group(1), g, l))
        return re.sub(r'{(.+?)}', repl, string)
    finally:
        del frame

The function replaces the regular expression, which replaces all the lines in brackets after running them through eval . Using inspect.currentframe (), we get the outer (calling) scope.

>>> a = 5
>>> s2 = 'a is {a}'
>>> print f(s2)
a is 5

Note: this can be easily extended to handle format flags like! R.

-2
source

Source: https://habr.com/ru/post/1690143/


All Articles