tl; ডাঃ / দ্রুত সমাধান
- উইলি নিলির ডিকোড / এনকোড করবেন না
- আপনার স্ট্রিংগুলি ইউটিএফ -8 এনকোডযুক্ত বলে মনে করবেন না
- আপনার কোডে যত তাড়াতাড়ি সম্ভব স্ট্রিংগুলি ইউনিকোড স্ট্রিংয়ে রূপান্তর করার চেষ্টা করুন
- আপনার লোকেলটি ঠিক করুন: পাইথন ৩.6-এ ইউনিকোডডেকোডেরর কীভাবে সমাধান করবেন?
- দ্রুত
reload
হ্যাকগুলি ব্যবহার করতে প্রলোভিত হবেন না
পাইথন ২.x-এ ইউনিকোড জেন - দীর্ঘ সংস্করণ
উত্স না দেখে এর মূল কারণটি জানা মুশকিল, তাই আমাকে সাধারণত কথা বলতে হবে।
UnicodeDecodeError: 'ascii' codec can't decode byte
সাধারণত যখন আপনি পাইথন ২.x রূপান্তর করার চেষ্টা করেন str
তখন মূল স্ট্রিংয়ের এনকোডিং নির্দিষ্ট না করে অ-এএসসিআইআইকে একটি ইউনিকোড স্ট্রিংয়ে রূপান্তর করতে পারেন ।
সংক্ষেপে, ইউনিকোড স্ট্রিংগুলি সম্পূর্ণ পৃথক পাইথন স্ট্রিং যা কোনও এনকোডিং ধারণ করে না। তারা কেবল ইউনিকোড পয়েন্ট কোড ধারণ করে এবং তাই পুরো বর্ণালী থেকে যে কোনও ইউনিকোড পয়েন্ট ধরে রাখতে পারে। স্ট্রিংগুলিতে এনকোডযুক্ত পাঠ্য থাকে, ইউটিএফ -8, ইউটিএফ -16, আইএসও-8895-1, জিবিকে, বিগ 5 ইত্যাদি স্ট্রিংগুলি ইউনিকোডে ডিকোড হয় এবং ইউনিকোডগুলি স্ট্রিংগুলিতে এনকোড থাকে । ফাইল এবং পাঠ্য ডেটা সর্বদা এনকোড স্ট্রিংগুলিতে স্থানান্তরিত হয়।
মার্কডাউন মডিউল লেখক সম্ভবত unicode()
বাকী কোডটির মান গেট হিসাবে ব্যবহার করবেন (যেখানে ব্যতিক্রম ছুঁড়েছে) - এটি ASCII রূপান্তর করবে বা বিদ্যমান ইউনিকোড স্ট্রিংগুলিকে নতুন ইউনিকোড স্ট্রিংয়ে পুনরায় মোড়ায়। মার্কডাউন লেখকগণ আগত স্ট্রিংটির এনকোডিংটি জানতে পারবেন না তাই মার্কডাউনে যাওয়ার আগে ইউনিকোড স্ট্রিংয়ের স্ট্রিংগুলি ডিকোড করার জন্য আপনার উপর নির্ভর করবে।
ইউনিকোড স্ট্রিংগুলি আপনার কোডে u
স্ট্রিংয়ের উপসর্গ ব্যবহার করে ঘোষণা করা যেতে পারে । যেমন
>>> my_u = u'my ünicôdé strįng'
>>> type(my_u)
<type 'unicode'>
ইউনিকোড স্ট্রিং ফাইল, ডাটাবেস এবং নেটওয়ার্ক মডিউল থেকেও আসতে পারে। যখন এটি হয়, আপনার এনকোডিং সম্পর্কে চিন্তা করার দরকার নেই।
Gotchas
str
আপনি স্পষ্টভাবে কল না করলেও ইউনিকোড থেকে রূপান্তর ঘটতে পারে unicode()
।
নিম্নলিখিত পরিস্থিতিতে UnicodeDecodeError
ব্যতিক্রম ঘটায় :
# Explicit conversion without encoding
unicode('€')
# New style format string into Unicode string
# Python will try to convert value string to Unicode first
u"The currency is: {}".format('€')
# Old style format string into Unicode string
# Python will try to convert value string to Unicode first
u'The currency is: %s' % '€'
# Append string to Unicode
# Python will try to convert string to Unicode first
u'The currency is: ' + '€'
উদাহরণ
নিম্নলিখিত চিত্রটিতে, আপনি café
টার্মিনালের ধরণের উপর নির্ভর করে শব্দটি কীভাবে "ইউটিএফ -8" বা "সিপি 1252" এনকোডিংয়ে এনকোড করা হয়েছে তা দেখতে পাবেন । উভয় উদাহরণে, caf
কেবল নিয়মিত আসকি। ইউটিএফ -8 এ é
দুটি বাইট ব্যবহার করে এনকোড করা হয়েছে। "সিপি 1252" তে, 0 0xE9 (এটি ইউনিকোড পয়েন্ট মান হিসাবে ঘটে (এটি কোনও কাকতালীয় ঘটনা নয়))। সঠিকটি decode()
আহ্বান করা হয়েছে এবং পাইথন ইউনিকোডে রূপান্তরটি সাফল্যজনক:
এই চিত্রটিতে, decode()
সাথে ডাকা হয় ascii
(যা unicode()
কোনও এনকোডিং না দিয়ে কল করার মতো )। যেহেতু এএসসিআইআই এর চেয়ে বেশি বাইট থাকতে পারে না 0x7F
, এটি একটি UnicodeDecodeError
ব্যতিক্রম ছুঁড়ে ফেলবে :
ইউনিকোড স্যান্ডউইচ
আপনার কোডটিতে একটি ইউনিকোড স্যান্ডউইচ গঠন করা ভাল অনুশীলন, যেখানে আপনি সমস্ত ইনকামিং ডেটা ইউনিকোড স্ট্রিংয়ে ডিকোড করেন, ইউনিকোডের সাথে কাজ করেন, তারপরে বেরোনোর পথে এনকোড str
করুন। এটি আপনাকে আপনার কোডের মাঝখানে স্ট্রিংগুলির এনকোডিং সম্পর্কে উদ্বেগ থেকে বাঁচায়।
ইনপুট / ডিকোড
সোর্স কোড
যদি আপনার সোর্স কোডে নন-এএসসিআইআই বেক করার প্রয়োজন হয় তবে কেবল একটি দিয়ে স্ট্রিংটির উপসর্গ রেখে ইউনিকোড স্ট্রিংগুলি তৈরি করুন u
। যেমন
u'Zürich'
পাইথনকে আপনার উত্স কোডটি ডিকোড করার অনুমতি দেওয়ার জন্য আপনার ফাইলের প্রকৃত এনকোডিংয়ের সাথে মিল রাখতে আপনাকে একটি এনকোডিং শিরোনাম যুক্ত করতে হবে। উদাহরণস্বরূপ, আপনার ফাইলটিকে 'ইউটিএফ -8' হিসাবে এনকোড করা থাকলে আপনি ব্যবহার করতে পারেন:
# encoding: utf-8
এটি কেবল তখনই প্রয়োজনীয় যখন আপনার উত্স কোডটিতে অ-ASCII থাকে ।
নথি পত্র
সাধারণত একটি ফাইল থেকে নন-এএসসিআইআই ডেটা পাওয়া যায়। io
মডিউল একটি TextWrapper যে ফ্লাইটে আপনার ফাইল decodes, একজন প্রদত্ত ব্যবহার উপলব্ধ encoding
। আপনাকে অবশ্যই ফাইলের জন্য সঠিক এনকোডিংটি ব্যবহার করতে হবে - এটি সহজেই অনুমান করা যায় না। উদাহরণস্বরূপ, একটি ইউটিএফ -8 ফাইলের জন্য:
import io
with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file:
my_unicode_string = my_file.read()
my_unicode_string
তাহলে মার্কডাউনে যাওয়ার জন্য উপযুক্ত হবে be যদি লাইনটি UnicodeDecodeError
থেকে একটি হয় read()
, তবে আপনি সম্ভবত ভুল এনকোডিং মানটি ব্যবহার করেছেন।
সিএসভি ফাইল
পাইথন ২.7 সিএসভি মডিউলটি অ-এসসিআইআই অক্ষরগুলিকে সমর্থন করে না 😩 Https://pypi.python.org/pypi/backports.csv- র সাহায্যে সহায়তার হাত রয়েছে ।
এটি উপরের মতো ব্যবহার করুন তবে এতে খোলা ফাইলটি পাস করুন:
from backports import csv
import io
with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file:
for row in csv.reader(my_file):
yield row
ডেটাবেস
বেশিরভাগ পাইথন ডাটাবেস ড্রাইভার ইউনিকোডে ডেটা ফিরিয়ে দিতে পারে তবে সাধারণত কিছুটা কনফিগারেশন প্রয়োজন। এসকিউএল ক্যোরির জন্য সর্বদা ইউনিকোড স্ট্রিং ব্যবহার করুন।
মাইএসকিউএল
সংযোগ স্ট্রিং এ যোগ করুন:
charset='utf8',
use_unicode=True
যেমন
>>> db = MySQLdb.connect(host="localhost", user='root', passwd='passwd', db='sandbox', use_unicode=True, charset="utf8")
পোস্টগ্রি
যোগ করুন
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
HTTP- র
ওয়েব পৃষ্ঠাগুলি প্রায় কোনও এনকোডিংয়ে এনকোড করা যায়। Content-type
হেডার একটি থাকা উচিত charset
এনকোডিং এ প্রজ্ঞান ক্ষেত্র। সামগ্রীটি তখন এই মানটির বিপরীতে ম্যানুয়ালি ডিকোড করা যায়। বিকল্পভাবে পাইথন-অনুরোধগুলি ইউনিকোডগুলিতে ফিরে আসে response.text
।
ম্যানুয়ালি
আপনার যদি স্ট্রিংগুলি ম্যানুয়ালিভাবে ডিকোড করতে হয় তবে আপনি সহজভাবে করতে পারেন my_string.decode(encoding)
যেখানে encoding
উপযুক্ত এনকোডিং। পাইথন ২.x সমর্থিত কোডেকগুলি এখানে দেওয়া হয়েছে: স্ট্যান্ডার্ড এনকোডিংস । আবার আপনি যদি তা পান UnicodeDecodeError
তবে সম্ভবত ভুল এনকোডিং পেয়েছেন।
স্যান্ডউইচের মাংস
ইউনিকোডের সাথে কাজ করুন যেমন আপনি সাধারণ স্টার্স করেন।
আউটপুট
stdout / মুদ্রণ
print
stdout প্রবাহের মাধ্যমে লেখেন। পাইথন stdout এ একটি এনকোডার কনফিগার করার চেষ্টা করে যাতে ইউনিকোডগুলি কনসোলের এনকোডিংয়ে এনকোড থাকে। উদাহরণস্বরূপ, একটি লিনাক্স শেল যদি locale
হয় en_GB.UTF-8
, আউটপুট এনকোড করা হবে না UTF-8
। উইন্ডোজে আপনি একটি 8 বিট কোড পৃষ্ঠাতে সীমাবদ্ধ থাকবেন।
দূষিত লোকেলের মতো একটি ভুলভাবে কনফিগার করা কনসোল অপ্রত্যাশিত মুদ্রণের ত্রুটির দিকে পরিচালিত করতে পারে। PYTHONIOENCODING
এনভায়রনমেন্ট ভেরিয়েবল stdout জন্য এনকোডিং জোর করতে পারে।
নথি পত্র
ইনপুটের মতোই io.open
ইউনিকোডগুলি স্বচ্ছভাবে এনকোডড বাইট স্ট্রিংগুলিতে রূপান্তর করতে ব্যবহার করা যেতে পারে।
তথ্যশালা
পড়ার জন্য একই কনফিগারেশনটি ইউনিকোডগুলি সরাসরি লেখার অনুমতি দেয়।
পাইথন ঘ
পাইথন 3 পাইথন ২.x এর চেয়ে বেশি ইউনিকোড সক্ষম নয়, তবে এটি বিষয়টিতে কিছুটা কম বিভ্রান্ত। যেমন নিয়মিত str
এখন একটি ইউনিকোড স্ট্রিং এবং str
এখন পুরানো bytes
।
ডিফল্ট এনকোডিংটি ইউটিএফ -8, সুতরাং যদি আপনি .decode()
কোনও এনকোডিং না দিয়ে বাইট স্ট্রিং করেন, পাইথন 3 ইউটিএফ -8 এনকোডিং ব্যবহার করে। এটি সম্ভবত 50% লোকের ইউনিকোড সমস্যা সমাধান করে।
তদ্ব্যতীত, open()
ডিফল্টরূপে পাঠ্য মোডে পরিচালনা করে, তাই ডিকোড করা str
(ইউনিকোডগুলি) প্রদান করে। এনকোডিংটি আপনার লোকেল থেকে উদ্ভূত, যা ইউএনএফ x সিস্টেমে ইউটিএফ -8 বা উইন্ডোজ বাক্সে একটি 8-বিট কোড পৃষ্ঠা, যেমন উইন্ডোজ -1211 এর মতো হয়।
কেন আপনার ব্যবহার করা উচিত নয় sys.setdefaultencoding('utf8')
এটি একটি বাজে হ্যাক (আপনার ব্যবহারের একটি কারণ রয়েছে reload
) যা কেবলমাত্র সমস্যার মুখোশ পাবে এবং পাইথন 3.x এ আপনার স্থানান্তরকে বাধাগ্রস্থ করবে। সমস্যাটি বুঝুন, মূল কারণটি ঠিক করুন এবং ইউনিকোড জেনটি উপভোগ করুন। দেখুন কেন আমরা পাই স্ক্রিপ্টে sys.setdeafultencoding ("utf-8") ব্যবহার করব না? বিস্তারি তথ্যের জন্য