web-dev-qa-db-ja.com

Python 3.6のフォーマットされた文字列リテラル(f-string)を古い3.x、2.x Pythonにインポートできますか?

新しいPython 3.6 f-stringsは、文字列の使いやすさの大きな飛躍のように思えます。古いインタープリターで実行されている可能性のある新しいプロジェクトに心から飛び入り採用したいと思います。 2.7、3.3-3.5のサポートは素晴らしいと思いますが、少なくともこれらをPython 3.5コードベースで使用したいと思います。古いインタープリターで使用するために3.6のフォーマットされた文字列リテラルをインポートするには? ?

f"Foo is {age} {units} old"のようなフォーマットされた文字列リテラルは変更を壊さないため、from __future__ import ...呼び出しには含まれないことを理解しています。しかし、変更はバックポートされていません(私の知る限り)f-stringsで記述する新しいコードは、Python 3.6+多くのプロジェクト。

36
zachd1_618

残念ながら、それを使用したい場合は、行列乗算演算子Python 3.6+および@またはPython 3.5+yield fromと同じ)と同じPython 3.4+が必要です。

これらは、コードの解釈方法に変更を加えたため、古いバージョンでインポートされたときにSyntaxErrorsをスローします。つまり、古いPythonにインポートされていない場所、またはevalまたはexecで保護されていない場所にそれらを配置する必要があります(後者2つはお勧めしません!)。

複数のpythonバージョンをサポートしたい場合、それらを簡単に使用することはできません。

13
MSeifert

future-fstrings はf-stringsをPython 2.7スクリプトにもたらします。(ドキュメントに基づいて3.3-3.5を想定しています。)

pip install future-fstrings経由でpipインストールしたら、コードの先頭に特別な行を配置する必要があります。その行は次のとおりです。

# -*- coding: future_fstrings -*-

次に、コード内でフォーマットされた文字列リテラル(f-strings)を使用できます。

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

ここに私が使用するものがあります:

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

locals()によって返された辞書をアンパック(**)します。これは、すべてのローカル変数を辞書として{variable_name: value}

これは、nonlocal(Python 3.0+)を使用してローカルスコープにインポートしない限り、外部スコープで宣言された変数では機能しません。

あなたも使用できます

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

文字列にグローバル変数を含めるため。

8
Yoily L

Fストリングは、fプレフィックスのトークン化時にインタープリターによって作成されます。その機能だけで互換性の可能性がすべて失われます。

最も近いショットは、次のようなキーワードのフォーマットを使用することです

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

互換性の要件が終了すると、より簡単にリファクタリングできます。

5
Uriel

f-string_f2format_ と呼ばれるバックポートコンパイラを作成しました。あなたが要求したように、f-stringリテラルをPython 3.6風味で書き、コンパイルしてJavaScriptの Babel と同様に、エンドユーザーが実行できる互換バージョン。

_f2format_は、バックポートコンパイラーのインテリジェントでありながら不完全なソリューションを提供します。ソースコードの元のレイアウトを維持しながら、f-stringリテラルを_str.format_メソッドに置き換えます。単純に使用できます

_f2format /path/to/the/file_or_directory_

すべてのPythonファイルを所定の場所に書き換えます。たとえば、

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

に変換されます

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

文字列の連結、変換、形式の指定、複数行およびユニコードはすべて適切に扱われます。また、_f2format_は、構文違反があった場合に元のファイルをアーカイブします。

3
Jarry Shaw

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
shouldsee