Can I import Python's 3.6's formatted string literals (f-strings) into older 3.x, 2.x Python?

僤鯓⒐⒋嵵緔 提交于 2019-12-03 00:59:04

Unfortunatly if you want to use it you must require Python 3.6+, same with the matrix multiplication operator @ and Python 3.5+ or yield from (Python 3.4+ I think)

These made changes to how the code is interpreted and thus throw SyntaxErrors when imported in older versions. That means you need to put them somewhere where these aren't imported in older Pythons or guarded by an eval or exec (I wouldn't recommend the latter two!).

So yes, you are right, if you want to support multiple python versions you can't use them easily.

future-fstrings brings f-strings to Python 2.7 scripts. (And I assume 3.3-3.5 based on the documentation.)

Once you pip install it via pip install future-fstrings, you have to place a special line at the top of your code. That line is:

# -*- coding: future_fstrings -*-

Then you can use formatted string literals (f-strings) within your code:

# -*- coding: future_fstrings -*-
var = 'f-string'
print(f'hello world, this is an {var}')

here's what I use:

text = "Foo is {age} {units} old".format(**locals())

it unpacks (**) the dict returned by locals() which has all your local variables as a dict {variable_name: value}

Note this will not work for variables declared in an outer scope, unless you import it to the local scope with nonlocal (Python 3.0+).

you can also use

text.format(**locals(),**globals())

to include global variables in your string.

The f-strings are created by the interpreter upon tokening the f prefix - that feature alone will kill any compatibility chances.

Your closest shot is to use the keyword formatting, like

'Foo is {age} {units} old'.format(age=age, units=units)

which can be more easily refactored upon the termination of requirement for compatibility.

I just wrote a back-port compiler for f-string, called f2format. Just as you requests, you may write f-string literals in Python 3.6 flavour, and compile to a compatible version for end-users to run, just like Babel for JavaScript.

f2format provides an intelligent, yet imperfect, solution of a back-port compiler. It shall replace f-string literals with str.format methods, whilst maintaining the original layout of source code. You can simply use

f2format /path/to/the/file_or_directory

which will rewrite all Python files in place. For instance,

var = f'foo{(1+2)*3:>5}bar{"a", "b"!r}boo'

will be converted to

var = ('foo{:>5}bar{!r}boo').format(((1+2)*3), ("a", "b"))

String concatenation, conversion, format specification, multi-lines and unicodes are all treated right. Also, f2format will archive original files in case there're any syntax breaches.

A dirty solution using simpleeval

import re
import simpleeval
test='_someString'
lst = ['_456']

s = '123123{lst[0]}{test}'

def template__format(template, context=None):
    if context is None:
        frame = inspect.currentframe()
        context = frame.f_back.f_locals        
        del frame
    ptn =  '([^{]?){([^}]+)}'
    class counter():
        i = -1

    def count(m):
        counter.i += 1
        return m.expand('\\1{%d}'%counter.i)

    template = re.sub(ptn,string=s, repl= count)
    exprs = [x[1] for x in re.findall(ptn,s)]
    vals = map(simpleeval.SimpleEval(names=context).eval,exprs)
    res = template.format(*vals)
    return res

print (template__format(s))

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!