2011-12-21 4 views
1

PEP3101で説明したように、追加のプレゼンテーションタイプを提供するためにFormatterを拡張できることがわかっていますが、これは私のニーズにとっては完全に遅すぎます。私は文字列のカスタムプレゼンテーションタイプを注入するための他のオプションがあるかも知りません。Python/Cythonカスタムフォーマッタの文字列プレゼンテーションタイプ

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

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

答えて

1

私は、サイモンではかなりオーバーヘッドが少ないようですが、これはPythonでやることができますが、ここではオーバーヘッドは分かりません。

pythonのドキュメントによれば、オブジェクトは__ format__メソッドを実装し、フォーマット仕様を受け取ることができます。 cythonでは、私自身のuobj型を実装しています。これは、str.formatに渡されたargsとkwargsのジェネリックとして機能します。 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または辞書)ユーザオブジェクトを格納することができ、次いで

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

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

そしてuobjに鋳造FMTの内部に発生するようにアクセスすることができます* argsと** kwargsの関数です。私のunittestsでintsが解析に失敗したことに気づいたような、ここで解決すべき詳細はまだいくつかあります.uobjは* uobjと** uobjでオブジェクトを変換するためにunpackする必要があります。リストのそれぞれのクローンと辞書とを含む。それでも、これは私のための最善の道であるようです。

編集

病気ここ http://docs.python.org/reference/datamodel.html#emulating-container-types

をコンテナタイプをエミュレート上に読んでいるようです