2

私は最近、.format()代わりに使用を開始することにしました%(この質問を参照してください)。{0},構文の代わりに{1}、次の使用法が許容されるかどうか疑問に思っています。

import os
def get_filename(player_name):
    for ext in ('jpg', 'jpeg', 'png'):
        filename = "data/avatars/{player_name}.{ext}".format(**locals())
        if os.path.exists(filename):
            return filename
    return None

私はその単純さが好きです - ローカル変数は文字列に入ります - しかし、上記のことをすべきではない理由があるかどうか疑問に思っています.

4

2 に答える 2

4

locals()(or globals()) をformat( or ) に渡す際の主な問題%は、多くの場合、フォーマット文字列が信頼できないソースから取得される可能性があり、望まない変数を公開するリスクがあることです。リテラル文字列をフォーマットするだけであれば問題ありませんが、信頼できないフォーマット文字列を使用する可能性がある場合は、何をしているのかについて非常に慎重に考える必要があります。

より小さな問題は、コードの一部の読者がlocals**構文を理解できず、その機能や機能の理由を理解するのに苦労することです。これはたいした議論ではありません。実際、Python の設計上の決定の多くは、これが良い議論になることはほとんどないことを確認することに帰着しているとさえ言えます。言語は、読者があなたが書いた Pythonic を理解/学習することを期待するのに十分な大きさです。しかし、それでも考える価値があります。

次に、スタイルの問題があります。数か月ごとに、この言語を使えばもっと簡単にできるはずだと提案する人が現れ、メーリング リストで議論が始まります。一部の人々は、これが「明示的ではなく暗黙的」に感じられると確信しています。他の人は同意しません。ここの魔法のローカルは pythonic ではないということはかなりうまくいっていると思います…しかし、明示的に渡す必要がある場合は、それでいいlocals()かもしれませんし、そうでないかもしれません。コンセンサスを集めていないほとんどのスタイルの議論と同様に、それは本当にあなた次第です. (ちなみに、formatAPI は最終的にこのような引数から生まれました。元の提案は、暗黙的なlocals.

しかし、最終的には、何を節約しているのかを考慮する必要があります。これを比較してください:

filename = "data/avatars/{player_name}.{ext}".format(**locals())

に:

filename = "data/avatars/{0}.{1}".format(player_name, ext)

あなたのバージョンは、より明確で、より明示的で、入力しやすく、さらには短くはありません。したがって、初心者が読むのを少し難しくしたり、コミュニティの一部に迷惑をかけたりするリスクは(たとえそれが悪い理由であっても)、メリットがない場合は価値がないと思います.

于 2013-03-28T19:25:05.987 に答える
1

上でコメントしたように、これは信頼できないソースでは使用しないでください。また、Pythonic であるほど明示的ではないかもしれません。

それを行う関数を定義することもできますが、適切なローカルにアクセスするには、フレーム処理を行う必要があります

def format_locals(string):
    return string.format(**sys._getframe().f_back.f_locals)

この種のパターンは適切ではなく、Pypy などはこの種のコードを最適化できません。

このコードを使用します (Python 2.6 のサポートが必要な場合を除き、インデックスを追加する必要があります)。

filename = 'data/avatars/{}.{}'.format(player_name, ext)
于 2013-03-28T19:28:23.290 に答える