බයිට් නූලකට පරිවර්තනය කරන්න


2350

බාහිර වැඩසටහනකින් සම්මත ප්‍රතිදානය ලබා ගැනීමට මම මෙම කේතය භාවිතා කරමි:

>>> from subprocess import *
>>> command_stdout = Popen(['ls', '-l'], stdout=PIPE).communicate()[0]

සන්නිවේදන () ක්‍රමය මඟින් බයිට් සමූහයක් ලබා දෙයි:

>>> command_stdout
b'total 0\n-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file1\n-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file2\n'

කෙසේ වෙතත්, සාමාන්‍ය පයිතන් නූලක් ලෙස ප්‍රතිදානය සමඟ වැඩ කිරීමට මම කැමතියි. ඒ නිසා මට එය මේ ආකාරයෙන් මුද්‍රණය කළ හැකිය:

>>> print(command_stdout)
-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file1
-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file2

මම සිතුවේ එය binascii.b2a_qp () ක්‍රමය සඳහා බවයි, නමුත් මම එය උත්සාහ කළ විට, මට නැවතත් එම බයිට් අරා ලැබුණි:

>>> binascii.b2a_qp(command_stdout)
b'total 0\n-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file1\n-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file2\n'

බයිට් අගය නැවත නූල් බවට පරිවර්තනය කරන්නේ කෙසේද? මම අදහස් කළේ, එය අතින් කිරීම වෙනුවට "බැටරි" භාවිතා කිරීමයි. පයිතන් 3 සමඟ එය හොඳින් වීමට මම කැමතියි.


49
ඇයි str(text_bytes)වැඩ කරන්නේ නැත්තේ ? මෙය මට විකාරයකි.
චාලි පාකර්

14
Har චාර්ලිපාර්කර් නිසා str(text_bytes)කේතන ක්‍රමය නියම කළ නොහැක. පෙළ_බයිට් වල ඇති දේ මත පදනම්ව, text_bytes.decode('cp1250) ` ප්‍රති to ලය විය හැක්කේ ඊට වඩා වෙනස් නූලකි text_bytes.decode('utf-8').
ක්‍රේග් ඇන්ඩර්සන්

7
එබැවින් strශ්‍රිතය තවදුරටත් සැබෑ නූලකට පරිවර්තනය නොවේ. කිසියම් හේතුවක් නිසා කේතන ක්‍රමයක් පැහැදිලිව පැවසීමට එක් අයෙක් මට හේතුව කියවීමට කම්මැලි ය. එය පරිවර්තනය කර utf-8ඔබේ කේතය ක්‍රියාත්මක වේදැයි බලන්න. උදාvar = var.decode('utf-8')
චාලි පාකර්

1
Ra ක්‍රේග් ඇන්ඩර්සන්: unicode_text = str(bytestring, character_encoding)පයිතන් 3 හි අපේක්ෂා කළ පරිදි ක්‍රියා කරයි. එය පෙළට විකේතනය කිරීම වෙනුවට පෙළ නිරූපණයක් නිපදවන unicode_text = bytestring.decode(character_encoding)යන්තම් str(bytes_obj)ඇති වියවුල්සහගත තත්ත්වය වළක්වා ගැනීම වඩා සුදුසු ය bytes_obj: str(b'\xb6', 'cp1252') == b'\xb6'.decode('cp1252') == '¶'සහstr(b'\xb6') == "b'\\xb6'" == repr(b'\xb6') != '¶'
jfs

Answers:


3735

නූලක් නිෂ්පාදනය කිරීම සඳහා ඔබට බයිට් වස්තුව විකේතනය කළ යුතුය:

>>> b"abcde"
b'abcde'

# utf-8 is used here because it is a very common encoding, but you
# need to use the encoding your data is actually in.
>>> b"abcde".decode("utf-8") 
'abcde'

61
භාවිතා "windows-1252"කිරීම විශ්වාසදායක නොවේ (උදා: වින්ඩෝස් හි වෙනත් භාෂා අනුවාද සඳහා), එය භාවිතා කිරීම වඩාත් සුදුසු sys.stdout.encodingනොවේද?
nikow

12
සමහර විට මෙය තව කෙනෙකුට උදව් වනු ඇත: සමහර විට ඔබ හිටපු TCP සන්නිවේදනය සඳහා බයිට් අරා භාවිතා කරයි. ඔබට බයිට් අරාව '\ x00' අකුරු කපා ඉවත් කිරීමට අවශ්‍ය නම් පහත පිළිතුර ප්‍රමාණවත් නොවේ. B'example \ x00 \ x00'.decode ('utf-8') භාවිතා කරන්න. තීරු ('\ x00') ඉන්පසු භාවිතා කරන්න.
Wookie88

2
මම එය bugs.python.org/issue17860 හි ලේඛනගත කිරීම පිළිබඳ දෝෂයක් පුරවා ඇත - පැච් එකක් යෝජනා කිරීමට නිදහස් වන්න. දායක වීමට අපහසු නම් - එය වැඩිදියුණු කරන්නේ කෙසේදැයි අදහස් දැක්වීම සාදරයෙන් පිළිගනිමු.
anatoly techtonik

45
පයිතන් 2.7.6 හි හැසිරවිය නොහැක b"\x80\x02\x03".decode("utf-8")-> UnicodeDecodeError: 'utf8' codec can't decode byte 0x80 in position 0: invalid start byte.
මාර්ටිනෝ

11
අන්තර්ගතය අහඹු ද්විමය අගයන් නම්, utf-8පරිවර්තනය අසාර්ථක වීමට ඉඩ ඇත. ඒ වෙනුවට @techtonik පිළිතුර බලන්න (පහළ) stackoverflow.com/a/27527728/198536
wallyk

218

ඔබට බයිට් නූල විකේතනය කර එය අක්ෂර (යුනිකෝඩ්) නූලකට හරවන්න.

පයිතන් 2 හි

encoding = 'utf-8'
'hello'.decode(encoding)

හෝ

unicode('hello', encoding)

පයිතන් 3 හි

encoding = 'utf-8'
b'hello'.decode(encoding)

හෝ

str(b'hello', encoding)

2
පයිතන් 3 හි, නූල් විචල්‍යයක තිබේ නම් කුමක් කළ යුතුද?
ඇල එම් එම්

1
@ අලාම්: එකම. ඔබට තිබේ variable = b'hello'නම්unicode_text = variable.decode(character_encoding)
jfs

184

මම හිතන්නේ මේ ක්‍රමය පහසුයි:

>>> bytes_data = [112, 52, 52]
>>> "".join(map(chr, bytes_data))
'p44'

6
ස්තූතියි, වෙන කවුරුත් නොකළ විට ඔබේ ක්‍රමය මා වෙනුවෙන් වැඩ කළා. මා සතුව කේතනය නොකරන ලද බයිට් අරා එකක් අවශ්‍ය විය. එය නැවත කේතනය කිරීමට ක්‍රමයක් සෙවීමට උත්සාහ කරමින් සිටි නිසා මට එය නූලකට විකේතනය කළ හැකිය. මෙම ක්රමය පරිපූර්ණ ලෙස ක්රියා කරයි!
leetNightshade

5
@leetNightshade: එහෙත් එය දරුණු ලෙස අකාර්යක්ෂමයි. ඔබට බයිට් අරා තිබේ නම් ඔබට විකේතනය කළ යුතුය.
මාර්ටිජන් පීටර්ස්

13
Art මාර්ටිජ් පීටර්ස් මම මේ අනෙක් පිළිතුරු සමඟ සරල මිණුම් දණ්ඩක් කළෙමි, ලකුණු 10,000 ක් ධාවනය කරමින් stackoverflow.com/a/3646405/353094 තවද ඉහත විසඳුම සෑම අවස්ථාවකදීම වඩා වේගවත් විය. පයිතන් 2.7.7 හි ලකුණු 10,000 ක් සඳහා එය මීටර් 8 ක් ගතවන අතර අනෙක් ඒවාට සාපේක්ෂව මීටර් 12 සහ 18 යි. ආදානය, පයිතන් අනුවාදය යනාදිය මත යම් වෙනසක් සිදුවිය හැකි බව මට විශ්වාසයි. මට එය මන්දගාමී බවක් නොපෙනේ.
leetNightshade

5
Ar මාටිජන් පීටර්ස් ඔව්. එබැවින් එම කරුණ සමඟ, අසන ලද ප්‍රශ්නයේ ශරීරයට මෙය හොඳම පිළිතුර නොවේ. මාතෘකාව නොමඟ යවන සුළුය, එසේ නොවේ ද? ඔහුට / ඇයට අවශ්‍ය වන්නේ බයිට් නූලක් සාමාන්‍ය නූලකට පරිවර්තනය කිරීමට මිස බයිට් අරාවකට නූලකට පරිවර්තනය කිරීමට නොවේ. අසන ලද ප්‍රශ්නයේ මාතෘකාව සඳහා මෙම පිළිතුර හොඳින් ක්‍රියාත්මක වේ.
leetNightshade

5
පයිතන් 3 සඳහා මෙය සමාන විය යුතුය bytes([112, 52, 52])- btw බයිට් යනු දේශීය විචල්‍යයකට නරක නමකි, එය හරියටම p3
බිල්ඩින් නිසා

96

ඔබ කේතන ක්‍රමය නොදන්නේ නම්, පයිතන් 3 සහ පයිතන් 2 අනුකූල ආකාරයෙන් ද්විමය ආදානය නූල් වලට කියවීමට, පුරාණ MS-DOS CP437 කේතන ක්‍රමය භාවිතා කරන්න:

PY3K = sys.version_info >= (3, 0)

lines = []
for line in stream:
    if not PY3K:
        lines.append(line)
    else:
        lines.append(line.decode('cp437'))

කේතීකරණය නොදන්නා හෙයින්, ඉංග්‍රීසි නොවන සංකේත අක්ෂර වලට පරිවර්තනය කිරීමට බලාපොරොත්තු වන්න cp437(ඉංග්‍රීසි අක්ෂර පරිවර්තනය නොකෙරේ, මන්ද ඒවා බොහෝ තනි බයිට් කේතීකරණ හා යූටීඑෆ් -8 සමඟ ගැලපේ).

අත්තනෝමතික ද්විමය ආදානය UTF-8 වෙත විකේතනය කිරීම අනාරක්ෂිත ය, මන්ද ඔබට මෙය ලැබෙනු ඇත:

>>> b'\x00\x01\xffsd'.decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 2: invalid
start byte

එම අදාළ latin-1අතුරුදහන් වූ ලකුණු Python 2. බලන්න සඳහා ජනප්රිය වූ, (ප්රකෘතිය?) Codepage පිරිසැලසුම Python කුප්රකට සමග යටපත් කරන්නේ නම් එය - ordinal not in range.

යාවත්කාලීන කිරීම 20150604 : surrogateescapeදත්ත නැතිවීම හා බිඳ වැටීම් නොමැතිව ද්විමය දත්ත වලට කේතනය කිරීමේ වැරදි උපාය මාර්ගයක් පයිතන් 3 සතුව ඇති බවට කටකතා පවතී , නමුත් [binary] -> [str] -> [binary]කාර්ය සාධනය සහ විශ්වසනීයත්වය යන දෙකම වලංගු කිරීම සඳහා එයට පරිවර්තන පරීක්ෂණ අවශ්‍ය වේ.

UPDATE 20170116 : Nearoo විසින් අදහස් දැක්වීමට ස්තූතියි - backslashreplaceදෝෂ හසුරුවන්නා සමඟ නොදන්නා සියලුම බයිට් වලින් ගැලවී යාමේ හැකියාවක් ද ඇත . එය ක්‍රියාත්මක වන්නේ පයිතන් 3 සඳහා පමණි, එබැවින් මෙම ක්‍රියාකාරීත්වය සමඟ වුවද ඔබට විවිධ පයිතන් අනුවාද වලින් නොගැලපෙන ප්‍රතිදානය ලැබෙනු ඇත:

PY3K = sys.version_info >= (3, 0)

lines = []
for line in stream:
    if not PY3K:
        lines.append(line)
    else:
        lines.append(line.decode('utf-8', 'backslashreplace'))

වැඩි විස්තර සඳහා පයිතන්ගේ යුනිකෝඩ් සහාය බලන්න.

UPDATE 20170119 : පයිතන් 2 සහ පයිතන් 3 යන දෙකටම වැඩ කරන ස්ලෑෂ් පැනීමේ විකේතනය ක්‍රියාත්මක කිරීමට මම තීරණය කළෙමි. එය cp437විසඳුමට වඩා මන්දගාමී විය යුතුය , නමුත් එය සෑම පයිතන් අනුවාදයකටම සමාන ප්‍රති results ල ලබා දිය යුතුය .

# --- preparation

import codecs

def slashescape(err):
    """ codecs error handler. err is UnicodeDecode instance. return
    a tuple with a replacement for the unencodable part of the input
    and a position where encoding should continue"""
    #print err, dir(err), err.start, err.end, err.object[:err.start]
    thebyte = err.object[err.start:err.end]
    repl = u'\\x'+hex(ord(thebyte))[2:]
    return (repl, err.end)

codecs.register_error('slashescape', slashescape)

# --- processing

stream = [b'\x80abc']

lines = []
for line in stream:
    lines.append(line.decode('utf-8', 'slashescape'))

6
නැතිවූ සංකේත ප්‍රතිස්ථාපනය කර ඉදිරියට යාමට යාන්ත්‍රණයක් පයිතන් විසින් සැපයිය යුතු යැයි මට හැඟේ.
anatoly techtonik

echtechtonik: මෙය python2 හි වැඩ කළ ආකාරයට අරාව මත ක්‍රියා නොකරනු ඇත.
user2284570

22 user2284570 ඔබ අදහස් කරන්නේ ලැයිස්තුවක්ද? එය අරා මත ක්‍රියා කළ යුත්තේ ඇයි? විශේෂයෙන් පාවෙන අරා ..
anatoly techtonik

ඔබට b'\x00\x01\xffsd'.decode('utf-8', 'ignore')පයිතන් 3 හි ඇති යුනිකෝඩ් දෝෂ නොසලකා හැරිය හැකිය .
ඇන්ටෝනිස් කලූ

3
atanatolytechtonik ගැලවීමේ අනුක්‍රමය නූලෙන් ඉවත් කර ඉදිරියට යාමට හැකියාවක් ඇත: ප්‍රති result ලය b'\x80abc'.decode("utf-8", "backslashreplace")වනු ඇත '\\x80abc'. මෙම තොරතුරු යුනිකෝඩ් ප්‍රලේඛන පිටුවෙන් ලබාගෙන ඇති අතර එය මෙම පිළිතුර ලිවීමෙන් පසුව යාවත්කාලීන කර ඇති බව පෙනේ.
නයිරූ

90

පයිතන් 3 හි, පෙරනිමි කේතන ක්‍රමය "utf-8"වන බැවින් ඔබට කෙලින්ම භාවිතා කළ හැකිය:

b'hello'.decode()

එය සමාන වේ

b'hello'.decode(encoding="utf-8")

අනෙක් අතට, පයිතන් 2 හි , පෙරනිමි එන්කෝඩ් කිරීම සඳහා පෙරනිමි එන්කෝඩින් කිරීම. මේ අනුව, ඔබ භාවිතා කළ යුත්තේ:

b'hello'.decode(encoding)

encodingඔබට අවශ්‍ය කේතන ක්‍රමය කොහිද ?

සටහන: පයිතන් 2.7 හි මූල පද තර්ක සඳහා සහය එක් කරන ලදි.


41

මම හිතන්නේ ඔබට මෙය ඇත්ත වශයෙන්ම අවශ්‍යයි:

>>> from subprocess import *
>>> command_stdout = Popen(['ls', '-l'], stdout=PIPE).communicate()[0]
>>> command_text = command_stdout.decode(encoding='windows-1252')

කුමන කේතන ක්‍රමයක් භාවිතා කළ යුතු දැයි ඔබ දැනගත යුතු බව හැර, ආරොන්ගේ පිළිතුර නිවැරදි ය . වින්ඩෝස් 'වින්ඩෝස් -1252' භාවිතා කරන බව මම විශ්වාස කරමි. එය වැදගත් වන්නේ ඔබේ අන්තර්ගතයේ අසාමාන්‍ය (ASCII නොවන) අක්ෂර කිහිපයක් තිබේ නම් පමණි, නමුත් එය වෙනසක් කරනු ඇත.

මාර්ගය වන විට, එය බව කරන්නේ එය කේතනාංකය දැන ඔබ එය කියන්න නම් නැති නිසා, ඔවුන් අතර, භූගෝලීය පිහිටීම පරිවර්තනය නොහැක: කාරණය Python ද්විමය සහ පෙළ දත්ත සඳහා විවිධ වර්ග දෙකක් භාවිතා වෙත ගෙන යන හේතුව වේ! ඔබ දන්නා එකම ක්‍රමය වින්ඩෝස් ප්‍රලේඛනය කියවීමයි (නැතහොත් එය මෙතැනින් කියවන්න).


3
open()පෙළ ප්‍රවාහයන් සඳහා ක්‍රියා කිරීම හෝ Popen()ඔබ එය සමත් වුවහොත් ඔබ universal_newlines=Trueසඳහා අක්ෂර කේතන ක්‍රමය locale.getpreferredencoding(False)ඉන්ද්‍රජාලිකව තීරණය කරයි ( පයිතන් 3.3+ හි).
jfs

2
'latin-1'සියලු කේත ලක්ෂ්‍යයන් සහිත වාචික කේතීකරණයක් වන අතර, එබැවින් ඔබේ පයිතන් සහය දක්වන ඕනෑම වර්ගයක බයිට් නූලක් effectively ලදායී ලෙස කියවීමට ඔබට එය භාවිතා කළ හැකිය (එබැවින් පයිතන් 2 හි වාචික, පයිතන් 3 සඳහා යුනිකෝඩ් වෙත).
ත්‍රිත්ව

ri ට්‍රිප්ලී: මොජිබාක් 'latin-1'ලබා ගැනීමට හොඳ ක්‍රමයකි. ද එහි Windows මත ඉන්ද්රජාලික ආදේශන ඇත: එය, තවත් අනූන උදා: එක් ක්රියාවලිය සිට නල දත්ත පුදුම හිතෙන දුෂ්කර ය dir: \xb6> - \x14(මාගේ පිළිතුර අවසානයේ උදාහරණයක් ලෙස)
JFS

33

විශ්ව_නිවයින් සත්‍ය ලෙස සකසන්න, එනම්

command_stdout = Popen(['ls', '-l'], stdout=PIPE, universal_newlines=True).communicate()[0]

5
මම මෙම ක්‍රමය භාවිතා කර ඇති අතර එය ක්‍රියාත්මක වේ. කෙසේ වෙතත්, එය ඔබගේ පද්ධතියේ පරිශීලක මනාපයන් මත පදනම්ව කේතන ක්‍රමයේ අනුමාන කිරීම පමණක් වන බැවින් එය වෙනත් විකල්ප තරම් ශක්තිමත් නොවේ. මෙය කරන්නේ එයයි, docs.python.org/3.4/library/subprocess.html: “විශ්ව_නිව්ලයින් සත්‍ය නම්, [stdin, stdout සහ stderr] විශ්වීය නව රේඛා ප්‍රකාරයේදී පෙළ ප්‍රවාහයන් ලෙස විවෘත වනු ඇත. .getpreferredencoding (අසත්‍යය).
twasbrillig

1
3.7 හි ඔබට text=Trueඒ වෙනුවට කළ හැකිය (සහ කළ යුතුය) universal_newlines=True.
බොරිස්

25

බයිට් අනුක්‍රමයක් පෙළක් ලෙස අර්ථ නිරූපණය කිරීම සඳහා, ඔබ අනුරූප අක්ෂර කේතනය දැන සිටිය යුතුය:

unicode_text = bytestring.decode(character_encoding)

උදාහරණයක්:

>>> b'\xc2\xb5'.decode('utf-8')
'µ'

lsවිධානය මඟින් පෙළ ලෙස අර්ථ දැක්විය නොහැකි ප්‍රතිදානය නිපදවිය හැකිය. යුනික්ස් හි ගොනු නාම කප්පාදුව b'/'සහ ශුන්‍යය හැර බයිට් අනුක්‍රමයක් විය හැකිය b'\0':

>>> open(bytes(range(0x100)).translate(None, b'\0/'), 'w').close()

Utf-8 කේතීකරණ භාවිතයෙන් එවැනි බයිට් සුප් විකේතනය කිරීමට උත්සාහ කරයි UnicodeDecodeError.

එය වඩාත් නරක විය හැකිය. විකේතනය නිහ ly ව අසමත් විය හැකි අතර ඔබ වැරදි නොගැලපෙන කේතීකරණයක් භාවිතා කරන්නේ නම් මොජිබේක් නිපදවිය හැකිය :

>>> '—'.encode('utf-8').decode('cp1252')
'—'

දත්ත දූෂිත නමුත් ඔබගේ වැඩසටහන අසාර්ථක වූ බව නොදැන සිටියි.

පොදුවේ ගත් කල, කුමන අක්ෂර කේතීකරණයක් භාවිතා කළ යුතුද යන්න බයිට් අනුක්‍රමය තුළම අන්තර්ගත නොවේ. ඔබට මෙම තොරතුරු සන්නිවේදනය කළ යුතුය. සමහර ප්‍රති come ල අනෙක් ඒවාට වඩා වැඩිය, එබැවින් අක්ෂර කේතන ක්‍රමය අනුමානchardet කළ හැකි මොඩියුලයක් පවතී . තනි පයිතන් ස්ක්‍රිප්ටයකට විවිධ ස්ථානවල අක්ෂර කේතන කිහිපයක් භාවිතා කළ හැකිය.


lsප්‍රතිනිර්මාණය කළ නොහැකි ගොනු නාමos.fsdecode() සඳහා පවා සාර්ථක වන ශ්‍රිතය භාවිතයෙන් පයිතන් නූලකට පරිවර්තනය කළ හැකිය (එය යුනික්ස් හි භාවිතා කරන sys.getfilesystemencoding()සහ surrogateescapeදෝෂ හසුරුවන්නා):

import os
import subprocess

output = os.fsdecode(subprocess.check_output('ls'))

මුල් බයිට් ලබා ගැනීමට, ඔබට භාවිතා කළ හැකිය os.fsencode().

ඔබ universal_newlines=Trueපරාමිතිය පසු කළහොත් බයිට් විකේතනය කිරීමට subprocessභාවිතා කරයි locale.getpreferredencoding(False). උදා: එය cp1252වින්ඩෝස් මත විය හැකිය .

පියාසර කරන බයිට් ප්‍රවාහය විකේතනය කිරීම සඳහා, io.TextIOWrapper() භාවිතා කළ හැකිය: උදාහරණය .

විවිධ විධානයන් ඒවායේ ප්‍රතිදානය සඳහා විවිධ අක්ෂර කේතීකරණ භාවිතා කළ හැකිය. උදා: dirඅභ්‍යන්තර විධානය ( cmd) cp437 භාවිතා කරයි. එහි ප්‍රතිදානය විකේතනය කිරීම සඳහා, ඔබට කේතීකරණය පැහැදිලිවම සම්මත කළ හැකිය (පයිතන් 3.6+):

output = subprocess.check_output('dir', shell=True, encoding='cp437')

ගොනු නාමයන් වෙනස් විය හැකිය os.listdir()(එය වින්ඩෝස් යුනිකෝඩ් ඒපීඅයි භාවිතා කරයි) උදා., U + 00B6 (¶) වෙනුවට U + 0014 අක්ෂරය පාලනය කිරීම සඳහා y පයිතන්ගේ cp437 කෝඩෙක් සිතියම් '\xb6'සමඟ ආදේශ කළ හැකිය . අත්තනෝමතික යුනිකෝඩ් අක්ෂර සහිත ගොනු නාමයන්ට සහය දැක්වීම සඳහා, පයිතන් නූලකට ASCII නොවන යුනිකෝඩ් අක්ෂර අඩංගු විය හැකි විකේතනය පවර්ෂෙල් ප්‍රතිදානය බලන්න. '\x14'b'\x14'


23

අතර @Aaron Maenpaa පිළිතුර පමණක් ක්රියා කරයි, පරිශීලක මෑතකදී ඉල්ලා :

ඊට වඩා සරල ක්‍රමයක් තිබේද? 'fhand.read (). විකේතනය ("ASCII")' [...] එය දිගු වේ!

ඔයාට පාවිච්චි කරන්න පුළුවන්:

command_stdout.decode()

decode()සතුව සම්මත තර්කය :

codecs.decode(obj, encoding='utf-8', errors='strict')


.decode()එය භාවිතා 'utf-8'කිරීම අසාර්ථක විය හැකිය (විධානයේ ප්‍රතිදානය වෙනත් අක්ෂර කේතීකරණයක් භාවිතා කරයි හෝ හඳුනාගත නොහැකි බයිට් අනුක්‍රමයක් ලබා දෙයි). ආදානය ascii (utf-8 හි උප කුලකයක්) වුවද .decode()ක්‍රියා කරයි.
jfs

16

මෙම ප්‍රශ්නය ඇත්ත වශයෙන්ම subprocessප්‍රතිදානය ගැන විමසන බැවින් Popen, කේතීකරණ මූල පදයක් පිළිගන්නා බැවින් ඔබට වඩාත් direct ජු ප්‍රවේශයක් ඇත (පයිතන් 3.6+ හි):

>>> from subprocess import Popen, PIPE
>>> text = Popen(['ls', '-l'], stdout=PIPE, encoding='utf-8').communicate()[0]
>>> type(text)
str
>>> print(text)
total 0
-rw-r--r-- 1 wim badger 0 May 31 12:45 some_file.txt

වෙනත් පරිශීලකයින් සඳහා පොදු පිළිතුර වන්නේ පෙළට බයිට් විකේතනය කිරීමයි:

>>> b'abcde'.decode()
'abcde'

කිසිදු තර්කයක් නොමැතිව, sys.getdefaultencoding()භාවිතා කරනු ඇත. ඔබගේ දත්ත එසේ නොවේ sys.getdefaultencoding()නම්, ඔබ decodeඇමතුමෙහි කේතන ක්‍රමය පැහැදිලිව සඳහන් කළ යුතුය :

>>> b'caf\xe9'.decode('cp1250')
'café'

3
නැතහොත් පයිතන් 3.7 සමඟ ඔබට text=Trueලබා දී ඇති කේතන ක්‍රමය (සකසා ඇත්නම්) හෝ වෙනත් ආකාරයකින් පද්ධතියේ පෙරනිමිය භාවිතා කරමින් stdin, stdout සහ stderr විකේතනය කිරීමට සමත් විය හැකිය . Popen(['ls', '-l'], stdout=PIPE, text=True).
බොරිස්

කේතීකරණය lsභාවිතයෙන් ප්‍රතිදානය විකේතනය කිරීම utf-8අසාර්ථක විය හැකිය ( 2016 සිට මගේ පිළිතුරෙහි උදාහරණය බලන්න ).
jfs

1
Or බොරිස්: encodingපරාමිතිය ලබා දෙන්නේ නම් textපරාමිතිය නොසලකා හරිනු ලැබේ.
jfs

11

උත්සාහ කිරීමෙන් ඔබ පහත සඳහන් දෑ ලබා ගත යුතු නම් decode():

AttributeError: 'str' වස්තුවට 'විකේතනය' යන ගුණාංග නොමැත

ඔබට කේතීකරණ වර්ගය කෙලින්ම වාත්තු කිරීමකින් නියම කළ හැකිය:

>>> my_byte_str
b'Hello World'

>>> str(my_byte_str, 'utf-8')
'Hello World'

6

වින්ඩෝස් පද්ධතිවල දත්ත සමඟ වැඩ කරන විට ( \r\nරේඛා අවසානය සමඟ ), මගේ පිළිතුර නම්

String = Bytes.decode("utf-8").replace("\r\n", "\n")

මන්ද? Multiline Input.txt සමඟ මෙය උත්සාහ කරන්න:

Bytes = open("Input.txt", "rb").read()
String = Bytes.decode("utf-8")
open("Output.txt", "w").write(String)

ඔබගේ සියලු රේඛා අවසානයන් දෙගුණ වේ (සිට \r\r\n), එය අතිරේක හිස් රේඛාවලට මග පාදයි. පයිතන්ගේ පෙළ කියවීමේ කාර්යයන් සාමාන්‍යයෙන් රේඛා අවසානය සාමාන්‍යකරණය කරයි, එවිට නූල් පමණක් භාවිතා \nවේ. ඔබට වින්ඩෝස් පද්ධතියකින් ද්විමය දත්ත ලැබෙන්නේ නම්, ඒ සඳහා පයිතන්ට අවස්ථාවක් නොමැත. මේ අනුව,

Bytes = open("Input.txt", "rb").read()
String = Bytes.decode("utf-8").replace("\r\n", "\n")
open("Output.txt", "w").write(String)

ඔබගේ මුල් ගොනුව අනුකරණය කරයි.


මම .replace("\r\n", "\n")මෙතරම් කාලයක් එකතු කිරීමක් සොයමින් සිටියෙමි . ඔබට HTML නිසියාකාරව ඉදිරිපත් කිරීමට අවශ්‍ය නම් මෙය පිළිතුරයි.
mhlavacka

5

මම ලැයිස්තුවක් පිරිසිදු කිරීම සඳහා කාර්යයක් කළා

def cleanLists(self, lista):
    lista = [x.strip() for x in lista]
    lista = [x.replace('\n', '') for x in lista]
    lista = [x.replace('\b', '') for x in lista]
    lista = [x.encode('utf8') for x in lista]
    lista = [x.decode('utf8') for x in lista]

    return lista

6
ඔබ ඇත්තටම සියලුම දාම හැකි .strip, .replace, .encode, ආදිය ඇමතුම් එක් ලැයිස්තුව අවබෝධය තුල පමණක් වෙනුවට එය වඩා පස් ගුණයක් එල්ලාවල මහතා වරක් ලැයිස්තුව පුරා වඩාත් කැපීපෙනේ.
ටේලර් එඩ්මිස්ටන්

1
AyTaylorEdmiston සමහර විට එය ප්‍රතිපාදන මත ඉතිරි වන නමුත් මෙහෙයුම් ගණන එලෙසම පවතිනු ඇත.
ජූලියන්

5

Python 3 සඳහා, මෙම ආරක්ෂාකාරී හා වන Pythonic සිට ආගමට හරවා ප්රවේශය byteසඳහා string:

def byte_to_str(bytes_or_str):
    if isinstance(bytes_or_str, bytes): # Check if it's in bytes
        print(bytes_or_str.decode('utf-8'))
    else:
        print("Object not of byte type")

byte_to_str(b'total 0\n-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file1\n-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file2\n')

ප්‍රතිදානය:

total 0
-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file1
-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file2

5
1) od බොඩැන්ග්ලි පැවසූ පරිදි, වර්ගය පරීක්ෂා කිරීම කිසිසේත් පයිතොනික් නොවේ. 2) ඔබ මෙසේ ලිවීය: කාර්යය "ලෙස නම් කර තිබේ byte_to_str" එය STR ආපසු ගම්ය වන, නමුත් එය පමණක් බවට පත් අගය මුද්රණය කරයි, සහ එය අපොහොසත් වන්නේ නම්, එය දෝෂ මුද්රණය කරයි (නමුත් ව්යතිරේකයක් මතු වන්නේ නැත). මෙම ප්‍රවේශය අවිධිමත් වන අතර bytes.decodeඔබ ලබා දුන් විසඳුම අපැහැදිලි කරයි.
cosmicFluke

3

Sys වෙතින් - පද්ධති විශේෂිත පරාමිතීන් සහ කාර්යයන් :

සම්මත ධාරාවන්ගෙන් / සිට ද්විමය දත්ත ලිවීමට හෝ කියවීමට, යටින් පවතින ද්විමය බෆරය භාවිතා කරන්න. උදාහරණයක් ලෙස, stdout වෙත බයිට් ලිවීමට, භාවිතා කරන්න sys.stdout.buffer.write(b'abc').


3
උප ක්‍රියාවලියට නළය දැනටමත් ද්විමය බෆරයකි . එහි ප්‍රති ing ලයක් ලෙස ඇති අගයෙන් නූල් අගයක් ලබා ගන්නේ කෙසේද යන්න ආමන්ත්‍රණය කිරීමට ඔබේ පිළිතුර අසමත් වේ bytes.
මාර්ටිජන් පීටර්ස්

1
def toString(string):    
    try:
        return v.decode("utf-8")
    except ValueError:
        return string

b = b'97.080.500'
s = '97.080.500'
print(toString(b))
print(toString(s))

1
මෙම කේතය ප්‍රශ්නයට පිළිතුරු දිය හැකි අතර, එය ගැටළුව විසඳන්නේ කෙසේද සහ / හෝ ඇයි යන්න පිළිබඳ අතිරේක සන්දර්භයක් ලබා දීමෙන් පිළිතුරේ දිගුකාලීන වටිනාකම වැඩි දියුණු වේ. අනාගතයේදී පා readers කයන් සඳහා ඔබ පිළිතුරු සපයන බව මතක තබා ගන්න, දැන් අසන පුද්ගලයා පමණක් නොවේ! පැහැදිලි කිරීමක් එක් කිරීමට කරුණාකර ඔබේ පිළිතුර සංස්කරණය කරන්න, සහ අදාළ වන සීමාවන් සහ උපකල්පන මොනවාද යන්න පිළිබඳ ඇඟවීමක් දෙන්න. මෙම පිළිතුර අනෙක් අයට වඩා සුදුසු වන්නේ ඇයිද යන්න සඳහන් කිරීමද හානියක් නොවේ.
දේව්-අයිඑල්

පැහැදිලි කිරීමක් පිළිවෙලට වනු ඇත.
පීටර් මෝර්ටෙන්සන්

1

පයිතන් 3.7 හි “ෂෙල් විධානයක් ධාවනය කර එහි ප්‍රතිදානය බයිට් වෙනුවට පෙළක් ලෙස ලබා ගන්න” යන ඔබේ විශේෂිත අවස්ථාව සඳහා, ඔබ භාවිතා කළ යුතු subprocess.runඅතර ඇතුල් විය යුතුය text=True(මෙන්ම capture_output=Trueප්‍රතිදානය ග්‍රහණය කර ගැනීමට)

command_result = subprocess.run(["ls", "-l"], capture_output=True, text=True)
command_result.stdout  # is a `str` containing your program's stdout

textකියනු ලබන කිරීම සඳහා භාවිතා universal_newlinesPython 3.7, සහ වෙනස් කරන ලදී (හොඳින්, aliased). ඔබට 3.7 ට පෙර පයිතන් අනුවාදයන්ට සහය දැක්වීමට අවශ්‍ය නම්, universal_newlines=Trueඒ වෙනුවට ඇතුල් වන්නtext=True


0

ඔබට ඕනෑම බයිට් පරිවර්තනය කිරීමට අවශ්‍ය නම්, නූල් බයිට් බවට පරිවර්තනය කිරීම පමණක් නොවේ:

with open("bytesfile", "rb") as infile:
    str = base64.b85encode(imageFile.read())

with open("bytesfile", "rb") as infile:
    str2 = json.dumps(list(infile.read()))

කෙසේ වෙතත් මෙය ඉතා කාර්යක්ෂම නොවේ. එය 2 MB පින්තූරයක් 9 MB බවට හරවනු ඇත.


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.