私はpython3でsprintfを実行したいが、%sが動作するための手動変換を行うことなく、生のバイトオブジェクトを使用したい。だから、バイトオブジェクトを「テンプレート」として取り出し、任意の数のオブジェクトを任意の数のオブジェクトとし、レンダリングされたバイトオブジェクトを返します。これは、python 2のsprintf%演算子が常に働いていた方法です。Python 3のバイトオブジェクトに対してsprintf形式の書式を設定するにはどうすればよいですか?
b'test %s %s %s' % (5, b'blah','strblah') # python3 ==> error
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: %b requires bytes, or an object that implements __bytes__, not 'int'
def to_bytes(arg):
if hasattr(arg,'encode'): return arg.encode()
if hasattr(arg,'decode'): return arg
return repr(arg).encode()
def render_bytes_template(btemplate : bytes, *args):
return btemplate % tuple(map(to_bytes,args))
render_bytes_template(b'this is how we have to write raw strings with unknown-typed arguments? %s %s %s',5,b'blah','strblah')
# output: b'this is how we have to render raw string templates with unknown-typed arguments? 5 blah strblah'
しかし、パイソン2に、それはちょうどに建てられています:
'example that just works %s %s %s' % (5,b'blah',u'strblah')
# output: 'example that just works 5 blah strblah'
は、Python 3でこれを行うが、まだのpython 2の同じ性能を達成するための方法はありますか?私に何かが足りないと教えてください。ここでのフォールバックは、cythonで実装することです(または、これに役立つPython 3のライブラリがありますか?)しかし、文字列オブジェクトの暗黙的なエンコード以外の標準ライブラリから削除された理由はまだ分かりません。 format_any()のようなバイトメソッドを追加できませんか?ところで
、それはこの警官アウトのように単純ではありません。
def render_bytes_template(btemplate : bytes, *args):
return (btemplate.decode() % args).encode()
は、私は不要なエンコード/デコードを行うにはしたくないが、バイトの引数はrepr'dの代わりにされているだけでなく、注射された生。
Python 3はバグからあなたを守り、Python 2では水の下に隠れてしまったことに注意してください。たとえば、 'unicode:%s'%(u'Ünîcódæ '、) 'を実行してください。 –