පයිතන් 3 හි නූල් බයිට් බවට පරිවර්තනය කිරීමට හොඳම ක්‍රමය කුමක්ද?


948

TypeError සඳහා වන පිළිතුරු වල දැක්වෙන පරිදි, නූලක් බයිට් බවට පරිවර්තනය කිරීම සඳහා ක්‍රම දෙකක් ඇති බව පෙනේ: 'str' ස්වාරක්ෂක අතුරුමුහුණතට සහය නොදක්වයි

මෙම ක්‍රම අතුරින් වඩා හොඳ හෝ වැඩි පයිතොනික් වනු ඇත්තේ කුමක්ද? නැතහොත් එය පුද්ගලික මනාපයක් පමණක්ද?

b = bytes(mystring, 'utf-8')

b = mystring.encode('utf-8')

49
කේතන / විකේතනය භාවිතා කිරීම වඩාත් සුලභ වන අතර සමහර විට වඩාත් පැහැදිලි වේ.
ලෙනාට් රෙජෙබ්‍රෝ

13
EnnLennartRegebro මම ඉවත් කරනවා. එය වඩාත් සුලභ වුවද, "බයිට් ()" කියවීම එහි ක්‍රියාකාරිත්වය කුමක්දැයි මම දනිමි, එන්කෝඩ් () එය බයිට් වලට කේතනය කරන බව මට හැඟෙන්නේ නැත.
m3nda

3
@ erm3nda එය දැනෙන තෙක් එය භාවිතා කිරීමට හොඳ හේතුවක් වන්නේ නම්, ඔබ යුනිකෝඩ් සෙන් වෙත එක් පියවරක් සමීප වේ.
ලෙනාට් රෙජෙබ්‍රෝ

4
EnnLennartRegebro bytes(item, "utf8")පැහැදිලිව ගම්‍ය වනවාට වඩා හොඳ බැවින් මට භාවිතා කිරීමට තරම් හොඳ යැයි මට හැඟේ , එබැවින් ... නිහ ly str.encode( )ව බයිට් වලට පෙරනිමි, එමඟින් ඔබ වඩාත් යුනිකෝඩ්-සෙන් නමුත් අඩු-පැහැදිලි-සෙන් බවට පත් කරයි. “පොදු” යනු මා අනුගමනය කිරීමට කැමති යෙදුමක් නොවේ. එසේම, සහ, අංකනයන්ට bytes(item, "utf8")වඩා වැඩිය . ඔබේ හේතු තේරුම් ගැනීමට මා එතරම් නොසිටින්නේ නම් මගේ සමාව ඉල්ලන්න. ඔබට ස්තුතියි. str()b"string"
m3nda

4
@ erm3nda ඔබ පිළිගත් පිළිතුර කියවා බැලුවහොත් ඔබට encode()ඇමතුමක් නොලැබෙන බව පෙනේ bytes(), එය අනෙක් පැත්තයි . ඇත්ත වශයෙන්ම එය ක්ෂණිකව පැහැදිලි නොවන අතර ඒ නිසා මම ප්‍රශ්නය ඇසුවෙමි.
මාර්ක් රැන්සම්

Answers:


616

ඔබ සඳහා ලියකියවිලි දෙස බැලුවහොත් bytes, එය ඔබට පෙන්වා දෙන්නේ bytearray:

bytearray ([ප්‍රභවය [, කේතන කිරීම [, දෝෂ]]])

නව බයිට් පෙළක් ආපසු එවන්න. බයිට්ආරේ වර්ගය යනු 0 <= x <256 පරාසයේ ඇති පූර්ණ සංඛ්‍යා වල විකෘති අනුක්‍රමයකි. විකෘති අනුක්‍රමික වර්ගවල විස්තර කර ඇති විකෘති අනුක්‍රමයන්හි සුපුරුදු ක්‍රම බොහොමයක් ඇත, එසේම බයිට් වර්ගයට ඇති බොහෝ ක්‍රම, බයිට් සහ බලන්න බයිට් අරා ක්‍රම.

අරාව විවිධ ආකාර කිහිපයකින් ආරම්භ කිරීමට විකල්ප ප්‍රභව පරාමිතිය භාවිතා කළ හැකිය:

එය නූලක් නම්, ඔබ කේතීකරණ (සහ විකල්ප වශයෙන්, දෝෂ) පරාමිතීන් ද ලබා දිය යුතුය; bytearray () පසුව str.encode () භාවිතා කරමින් නූල බයිට් බවට පරිවර්තනය කරයි.

එය පූර්ණ සංඛ්‍යාවක් නම්, අරාවෙහි එම ප්‍රමාණය ඇති අතර එය ශුන්‍ය බයිට් වලින් ආරම්භ වේ.

එය බෆර් අතුරුමුහුණතට අනුකූල වන වස්තුවක් නම්, බයිට් අරාව ආරම්භ කිරීම සඳහා වස්තුව කියවීමට පමණක් ඇති බෆරයක් භාවිතා කරනු ඇත.

එය පුනරාවර්තනය කළ හැකි නම්, එය අරාවෙහි ආරම්භක අන්තර්ගතයන් ලෙස භාවිතා කරන 0 <= x <256 පරාසය තුළ ඇති පූර්ණ සංඛ්‍යා නැවත ලබා ගත හැකි විය යුතුය.

තර්කයක් නොමැතිව, 0 ප්‍රමාණයේ අරාවක් නිර්මාණය වේ.

එබැවින් bytesනූලක් කේතනය කිරීමට වඩා වැඩි යමක් කළ හැකිය. පයිතොනික් එය අර්ථවත් වන ඕනෑම ආකාරයක ප්‍රභව පරාමිතියක් සමඟ ඉදිකිරීම්කරු ඇමතීමට ඔබට ඉඩ සලසයි.

නූලක් කේතනය some_string.encode(encoding)කිරීම සඳහා, එය ඉදිකිරීම්කරු භාවිතා කිරීමට වඩා පයිතොනික් යැයි මම සිතමි , මන්ද එය වඩාත්ම ස්වයං ලේඛනගත කිරීම වන බැවිනි - "මෙම නූල ගෙන මෙම කේතීකරණය සමඟ එය කේතනය කරන්න" වඩා පැහැදිලි ය bytes(some_string, encoding)- ඔබ භාවිතා කරන විට පැහැදිලි ක්‍රියාපදයක් නොමැත ඉදිකිරීම්කරු.

සංස්කරණය කරන්න: මම පයිතන් ප්‍රභවය පරීක්ෂා කළෙමි. ඔබ CPythonbytes භාවිතා කිරීම සඳහා යුනිකෝඩ් නූලක් පසු කළහොත් , එය PyUnicode_AsEncodedString ලෙස හැඳින්වේ , එය ක්‍රියාත්මක කිරීම encode; ඒ නිසා ඔබ encodeඔබම අමතන්නේ නම් ඔබ යම් තරමක උදාසීනත්වයක් මඟ හැරේ .

එසේම, සර්ඩාලිස්ගේ ප්‍රකාශය බලන්න - unicode_string.encode(encoding)එය වඩාත් පයිතොනික් වන්නේ එහි ප්‍රතිලෝම byte_string.decode(encoding)හා සමමිතිය කදිම බැවිනි.


81
+1 හොඳ තර්කයක් සහ පයිතන් ලියකියවිලි වලින් උපුටා දැක්වීම් සඳහා. ද unicode_string.encode(encoding)සමග අවසරයෙන් තරග bytearray.decode(encoding)ඔබ ඔබේ සංගීත නැවත අවශ්ය වන විට.
සර්ඩාලිස්

6
bytearrayඔබට විකෘති වස්තුවක් අවශ්‍ය වූ විට භාවිතා වේ. ඔබ සරල සඳහා එය අවශ්ය නැහැ strbytesගෙවීම් නැත.
හැම්ස්ටර්ජීන්

8
@EugeneHomyakov මෙම සමග ගෑවිලාවත් නැත bytearrayසඳහා ලේඛනයක් බව හැර bytesවිස්තර දෙන්න එපා, ඔවුන් හුදෙක් "මෙම ක මා තුලද අනුවාදය වේ කියන්න bytearrayමම එතැනින් උපුටා ඕනේ."
agf

2
යන්තම් සටහනක් ඔබ වැලක් කිරීමට ද්විමය දත්ත බවට පරිවර්තනය කිරීමට උත්සාහ කරන්නේ නම්, ඔබ වැනි භාවිතය දෙයක් කිරීමට බොහෝ දුරට ඉඩ අවශ්ය වේ බවත්, byte_string.decode('latin-1')ලෙස utf-8, සමස්ත පරාසය 0x00 0xFF (0-255) වෙත ආවරණය කරන්නේ නැහැ පිඹුරා පරීක්ෂා ලේඛන සඳහා වැඩි විස්තර.
iggy12345

2
tl;drප්‍රයෝජනවත් වනු ඇත
techkuz

402

එය සිතනවාට වඩා පහසු ය:

my_str = "hello world"
my_str_as_bytes = str.encode(my_str)
type(my_str_as_bytes) # ensure it is byte representation
my_decoded_str = my_str_as_bytes.decode()
type(my_decoded_str) # ensure it is string representation

45
ඔහු එය කරන්නේ කෙසේදැයි දනී, ඔහු විමසන්නේ වඩා හොඳ කුමන මාර්ගයද යන්නයි. කරුණාකර ප්‍රශ්නය නැවත කියවන්න.
agf

31
FYI: str.decode (බයිට්) මට වැඩ කටයුතු කළේ නැත (Python 3.3.3 "වර්ගය වස්තුව 'STR' කිසිදු විශේෂණය 'විකේතනය' ඇත" බවයි) මට bytes.decode භාවිතා () ඒ වෙනුවට
මයික්

6
Ike මයික්: obj.method()සින්ටැක්ස් වෙනුවට cls.method(obj)සින්ටැක්ස් භාවිතා කරන්න, එනම් භාවිතා කරන්න bytestring = unicode_text.encode(encoding)සහ unicode_text = bytestring.decode(encoding).
jfs

3
... එනම්, ඔබ අනවශ්‍ය ලෙස අසීමිත ක්‍රමවේදයක් සකසා, පසුව එය selfපළමු තර්කය ලෙස සම්මත කිරීම ලෙස හැඳින්වේ
ඇන්ටි හපාල

2
@KolobCanyon ප්‍රශ්නය දැනටමත් එය කළ හැකි නිවැරදි මාර්ගය පෙන්වයි the නූලට encodeබැඳී ඇති ක්‍රමයක් ලෙස අමතන්න . මෙම පිළිතුරෙන් ඇඟවෙන්නේ ඔබ ඒ වෙනුවට නොබැඳි ක්‍රමය අමතා එය නූල් පසු කළ යුතු බවයි. පිළිතුරේ ඇති එකම නව තොරතුරු එය වන අතර එය වැරදිය.
abarnert

161

මෙම පරම හොඳම ක්රමය 2 වත්, නමුත් 3 වන. පයිතන් 3.0 සිට පෙරනිමිය දක්වා වූ පළමු පරාමිතිය . මේ අනුව හොඳම ක්‍රමය එයයිencode 'utf-8'

b = mystring.encode()

මෙයද වේගවත් වනු ඇත, මන්ද පෙරනිමි තර්කය "utf-8"සී කේතයේ ඇති නූලට නොව NULL, පරීක්ෂා කිරීමට වඩා වේගවත් වේ!

මෙන්න වේලාවන් කිහිපයක්:

In [1]: %timeit -r 10 'abc'.encode('utf-8')
The slowest run took 38.07 times longer than the fastest. 
This could mean that an intermediate result is being cached.
10000000 loops, best of 10: 183 ns per loop

In [2]: %timeit -r 10 'abc'.encode()
The slowest run took 27.34 times longer than the fastest. 
This could mean that an intermediate result is being cached.
10000000 loops, best of 10: 137 ns per loop

අනතුරු ඇඟවීම නොතකා නැවත නැවත ධාවනය කිරීමෙන් පසු කාලය ඉතා ස්ථාවර විය - අපගමනය ඩොලර් 2 ක් පමණි.


encode()තර්කයක් නොමැතිව භාවිතා කිරීම පයිතන් 2 අනුකූල නොවේ, පයිතන් 2 හි පෙරනිමි අක්ෂර කේතනය ASCII වේ.

>>> 'äöä'.encode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)

2
මෙහි සැලකිය යුතු වෙනසක් ඇත. (අ) නූල පිරිසිදු ASCII වන අතර, එයින් අදහස් වන්නේ අභ්‍යන්තර ආචයනය දැනටමත් UTF-8 අනුවාදය වන බැවින් කෝඩෙක් දෙස බැලීමේදී ඇති එකම පිරිවැය පාහේ වන අතර (ආ) නූල ඉතා කුඩාය , එබැවින් ඔබට කේතනය කිරීමට සිදු වුවද, එය එතරම් වෙනසක් නොකරනු ඇත. කියන්න, කියන්න '\u00012345'*10000. දෙදෙනාම මගේ ලැප්ටොප් පරිගණකයේ 28.8us ගන්නවා; වටකුරු දෝෂය නිසා අමතර 50ns නැති වී යයි. ඇත්ත වශයෙන්ම මෙය ඉතා ආන්තික උදාහරණයකි - නමුත් 'abc'එය ප්‍රතිවිරුද්ධ දිශාවට අන්ත වේ.
abarnert

ar බාර්නර්ට් ඇත්ත, නමුත් එසේ වුවද, තර්කය නූල් ලෙස සම්මත කිරීමට හේතුවක් නැත.
ඇන්ටි හාපාල

මේ අනුව, සුපුරුදු තර්ක සෑම විටම දේවල් කිරීමට “නියත වශයෙන්ම හොඳම ක්‍රමය” වේ, නේද? සී කේතය සාකච්ඡා කිරීම ගැන නම් මේ ආකාරයේ වේග විශ්ලේෂණය අතිශයෝක්තියක් ලෙස හැඟෙනු ඇත. අර්ථකථනය කරන ලද භාෂාවකින්, එය මට නිහ .ව සිටියි.
hmijail ශෝකය ඉල්ලා අස්වන්නන්

1
mhmijail සුපුරුදු තර්ක අගයන් පැහැදිලිව ටයිප් කිරීමෙන් ඔබට කිසිවක් දිනා ගත නොහැක - වැඩි යතුරු එබීම්, විශාල කේතයක් වන අතර එයද මන්දගාමී වේ.
ඇන්ටි හාපාල
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.