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

前端 未结 8 1320
臣服心动
臣服心动 2020-12-15 02:27

The new Python 3.6 f-strings seem like a huge jump in string usability to me, and I would love to jump in and adopt them whole heartedly on new projects which might be runni

相关标签:
8条回答
  • 2020-12-15 03: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.

    0 讨论(0)
  • 2020-12-15 03:09

    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}')
    
    0 讨论(0)
  • 2020-12-15 03:09

    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.

    0 讨论(0)
  • 2020-12-15 03:12

    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.

    0 讨论(0)
  • 2020-12-15 03:13

    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))
    
    
    0 讨论(0)
  • 2020-12-15 03:19

    I've been using 'str'.format(**locals()) for a while but made this after a while because the additional code was a bit cumbersome for each statement

    def f(string):
        """
        Poor man's f-string for older python versions
        """
        import inspect
    
        frame = inspect.currentframe().f_back
    
        v = dict(**frame.f_globals)
        v.update(**frame.f_locals)
    
        return string.format(string, **v)
    
    # Example
    GLOBAL = 123
    
    
    def main():
        foo = 'foo'
        bar = 'bar'
    
        print(f('{foo} != {bar} - global is {GLOBAL}'))
    
    
    if __name__ == '__main__':
        main()
    
    0 讨论(0)
提交回复
热议问题