Chcę zrobić sprintf na python3, ale z obiektami surowych bajtów, bez konieczności wykonywania ręcznych konwersji dla% s do pracy. Zatem weź obiekt bajtowy jako "szablon", a także dowolną liczbę obiektów dowolnego typu i zwróć obiekt renderowanych bajtów. W ten sposób operator sprintf% Pythona 2 zawsze działał.Jak uzyskać formatowanie w formacie sprintf dla obiektów bajtów w pythonie 3?
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'
Ale w Pythonie 2, to jest po prostu zbudowany w:
'example that just works %s %s %s' % (5,b'blah',u'strblah')
# output: 'example that just works 5 blah strblah'
Czy istnieje sposób, aby zrobić to w Pythonie 3, ale wciąż osiągnąć taką samą wydajność python 2? Proszę powiedz mi, że czegoś mi brakuje. Zastąpienie tutaj polega na implementacji w cytoncie (lub czy istnieją tam biblioteki dla pythona 3, które pomagają w tym?), Ale nadal nie widzą powodu, dla którego zostały usunięte z biblioteki standardowej innej niż niejawne kodowanie obiektu string. Czy nie możemy po prostu dodać metody bajtów, takich jak format_any()?
Nawiasem mówiąc, to nie jest tak proste, jak to cop-out:
def render_bytes_template(btemplate : bytes, *args):
return (btemplate.decode() % args).encode()
Nie tylko ja nie chcę robić niepotrzebnego kodowanie/dekodowanie, ale args bajty są repr'd zamiast wstrzykiwany na surowo.
Zauważ, że Python 3 chroni cię teraz przed błędami, które zostały ukryte pod linią wodną w Pythonie 2. Spróbuj ''unicode:% s'% (u'Ünîcódæ,)' na przykład na rozmiar. –