14

{}python2.7+ スタイルの文字列フォーマット (たとえば、 sにインデックスなし) を持つ何千行もの Python コードがあります。

"{} {}".format('foo', 'bar')

インデックスを必要とするpython2.6 でこのコードを実行する必要があります。

python2.6でこのコードを実行できるようにする簡単な方法を誰かが知っているかどうか疑問に思っています。from __future__ import blah問題の解決策があれば最高です。見当たりません。それらの線に沿った何かが私の最初の選択です。

2 番目に遠いのは、少なくとも明白なケースでは、インデックスを追加するプロセスを自動化できるスクリプトです。

"{0} {1}".format('foo', 'bar')
4

4 に答える 4

7

空白を完全に保持するわけではなく、おそらくもう少し賢くすることができますが、正規表現や外部パーサーに頼ることなく、少なくとも Python 文字列 (アポストロフィ/引用符/複数行) を正しく識別します。

import tokenize
from itertools import count
import re

with open('your_file') as fin:
    output = []
    tokens = tokenize.generate_tokens(fin.readline)
    for num, val in (token[:2] for token in tokens):
        if num == tokenize.STRING:
            val = re.sub('{}', lambda L, c=count(): '{{{0}}}'.format(next(c)), val)
        output.append((num, val))

print tokenize.untokenize(output) # write to file instead...

入力例:

s = "{} {}".format('foo', 'bar')
if something:
    do_something('{} {} {}'.format(1, 2, 3))

出力例 (わずかにあいまいな空白に注意してください):

s ="{0} {1}".format ('foo','bar')
if something :
    do_something ('{0} {1} {2}'.format (1 ,2 ,3 ))
于 2013-12-11T17:18:38.900 に答える
0

たぶん、次のような古き良き sed-regex です。

sed source.py -e 's/{}/%s/g; s/\.format(/ % (/'

あなたの例は次のように変更されます:

"%s %s" % ('foo', 'bar')

ファンシーな新しいスタイル.format()を失うことは認められますが、些細な値の挿入にはほとんど役に立ちません。

于 2013-12-11T16:54:30.320 に答える
0

フォーマット文字列を再フォーマットする関数を定義できます。

def reformat(s):
    return "".join("".join((x, str(i), "}")) 
                   for i, x in list(enumerate(s.split("}")))[:-1])
于 2013-12-11T16:25:48.353 に答える
0

変換スクリプトは非常に単純です。正規表現に置き換える文字列を見つけることができます:

fmt = "['\"][^'\"]*{}.*?['\"]\.format"

str1 = "x; '{} {}'.format(['foo', 'bar'])"
str2 = "This is a function; 'First is {}, second is {}'.format(['x1', 'x2']); some more code"
str3 = 'This doesn't have anything but a format. format(x)'
str4 = "This has an old-style format; '{0} {1}'.format(['some', 'list'])"
str5 = "'{0}'.format(1); '{} {}'.format(['x', 'y'])"

def add_format_indices(instr):
    text = instr.group(0)
    i = 0
    while '{}' in text:
        text = text.replace('{}', '{%d}'%i, 1)
        i = i+1
    return text

def reformat_text(text):
    return re.sub(fmt, add_format_indices, text)

reformat_text(str1)
"x; '{0} {1}'.format(['foo', 'bar'])"
reformat_text(str2)
"This is a function; 'First is {0}, second is {1}'.format(['x1', 'x2']); some more code"
reformat_text(str3)
"This doesn't have anything but a format. format(x)"
reformat_text(str4)
"This has an old-style format; '{0} {1}'.format(['some', 'list'])"
reformat_text(str5)
"'{0}'.format(1); '{0} {1}'.format(['x', 'y'])"

これでファイル全体を投げることができると思います。おそらく add_format_indices のより高速な実装を見つけることができますが、明らかにそれはあまりテストされていません。

import __past__. _

于 2013-12-11T16:55:12.140 に答える