1

PEP3101 で説明されているように、Formatter を拡張して追加のプレゼンテーション タイプを提供できることはわかっていますが、これは私のニーズにはまったく遅すぎます。文字列のカスタム表示タイプを挿入するための他のオプションが何か知りたいです。

現在、頭に浮かぶ他の唯一のオプションは、文字列の {vars} を検査し、プレゼンテーションの種類とインデックスに注意し、カスタムのプレゼンテーションの種類と形式を取り除き、必要に応じて結果を書式設定することです。

フォーマットの速度を利用しながら、後処理を回避する他のオプションはありますか?

4

1 に答える 1

1

私は cython のオーバーヘッドが大幅に少ないと思われる解決策を考え出しましたが、同じことは Python で行うことができ、ここで例を提供することはできません (オーバーヘッドについてはわかりません)。

python docs によると、オブジェクトは __ format__ メソッドを実装し、フォーマット仕様を受け取ることができます。cython Im では、str.format に渡される args と kwargs のジェネリックとして機能する独自の uobj タイプを実装しています。Python での同じこと ( < および > をエスケープするための一般的な例として) は、次のようになります。

class uobj:
    def __init__(self, obj):
        self.obj = obj
    def __format__(self, format_spec):
        if format_spec == 's':
            return str(self.obj)
        else:
            # edit, shoehorning this in for completeness
            # to call an original format spec as should probably
            # happen after you do your own processing, use __format__
            if isinstance(self.obj, (int, float)):
                return self.obj.__format__(format_spec)
                # so then a :.2f spec on uobj(123.456) would work as expected
            return str(self.obj).replace('<', '&lt;').replace('>', '&gt;')
    def __getitem__(self, key):
        return uobj(self.obj[key])

これで、uobj はユーザー オブジェクト (次の例では str または dict) を格納し、次のようにアクセスできるようになりました。

d = uobj({'a': '<b>asdf'})
s = uobj('<span>qwer</span>')
'{0:s} {d[a]}'.format(s, d=d)

# ouputs: '<span>qwer</span>&lt;asdf'

また、*args および **kwargs の fmt 関数内で uobj へのキャストが行われる場所。ここで解決すべき詳細がまだいくつかあります。たとえば、ユニットテストで int の解析に失敗したことに気付きました。また、オンデマンドでオブジェクトを変換するには、*uobj および **uobj を介して uobj をアンパック可能にする必要がありますが、これを次のように分割する必要があるかもしれません。リストと辞書のそれぞれのクローン。それでも、これは私にとって最良の道のようです。

編集

ここでコンテナタイプをエミュレートすることについて読んでいないようです http://docs.python.org/reference/datamodel.html#emulating-container-types

于 2011-12-22T06:48:20.027 に答える