পাইথন 3 এ স্ট্রিংকে বাইটে রূপান্তর করার সর্বোত্তম উপায়?


858

স্ট্রিংকে বাইটে রূপান্তর করার জন্য দুটি ভিন্ন উপায় রয়েছে বলে মনে হয়, টাইপইয়েরারের উত্তরে দেখা গেছে : 'str' বাফার ইন্টারফেসটিকে সমর্থন করে না

এর মধ্যে কোন পদ্ধতিটি ভাল বা বেশি পাইথোনিক হতে পারে? নাকি এটি কেবল ব্যক্তিগত পছন্দের বিষয়?

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

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

42
এনকোড / ডিকোড ব্যবহার বেশি সাধারণ এবং সম্ভবত আরও পরিষ্কার।
লেনার্ট রেজেব্রো

11
@ লেনার্টেরেজিব্রো এমনকি যদি এটি আরও সাধারণ হয় তবে "বাইটস ()" পড়ার পরে আমি জানি যে এটি কী করছে, যখন এনকোড () আমাকে বাইটগুলিতে এনকোডিং করছে তা অনুভব করবেন না।
m3nda

2
@ erm3nda এটি ব্যবহার না করা ভাল কারণ এটি যতক্ষণ না মনে হয় ততক্ষণে আপনি ইউনিকোড জেনের এক ধাপ কাছে।
লেনার্ট রেগেব্রো

3
@ লেনার্টজেজব্রো আমি কেবল ব্যবহারের পক্ষে যথেষ্ট ভাল অনুভব করছি bytes(item, "utf8"), কারণ স্পষ্টতই অন্তর্নিহিতের চেয়ে ভাল, তাই ... str.encode( )বাইটে চুপচাপ ডিফল্ট, আপনাকে আরও ইউনিকোড-জেন কিন্তু কম স্পষ্ট-জেন করে তুলবে। এছাড়াও "সাধারণ" কোনও শব্দটি আমি অনুসরণ করতে পছন্দ করি না। এছাড়াও, bytes(item, "utf8")আরও বেশি str(), এবং b"string"স্বরলিপিগুলি পছন্দ করে। আমি আপনার কারণগুলি বুঝতে যদি এতই কূট হয় তবে আমার ক্ষমা চাই। ধন্যবাদ.
m3nda

4
@ erm3nda আপনি যদি স্বীকৃত উত্তরটি পড়ে থাকেন তবে আপনি দেখতে পাবেন যে এটি encode()কল করে না bytes(), এটি অন্যভাবে। অবশ্যই এটি তাত্ক্ষণিকভাবে স্পষ্ট নয় যে কারণে আমি প্রশ্নটি জিজ্ঞাসা করেছি।
মার্ক রান্সম

উত্তর:


569

আপনি যদি দস্তাবেজের দিকে নজর দেন তবে bytesএটি আপনাকে নির্দেশ করে bytearray:

বাইটারি ([উত্স [, এনকোডিং [, ত্রুটি]]])

বাইটগুলির একটি নতুন অ্যারে ফিরে আসুন। বাইটেরে টাইপটি 0 <= x <256 পরিসীমাটিতে পূর্ণসংখ্যার একটি পরিবর্তনীয় ক্রম হয় It বাইট অ্যারে পদ্ধতি।

Differentচ্ছিক উত্স প্যারামিটারটি কয়েকটি বিভিন্ন উপায়ে অ্যারে শুরু করতে ব্যবহার করা যেতে পারে:

যদি এটি একটি স্ট্রিং হয় তবে আপনাকে অবশ্যই এনকোডিং (এবং optionচ্ছিকভাবে ত্রুটি) পরামিতিগুলি দিতে হবে; bytearray () তারপরে স্ট্রিংকে স্ট্রেনকোড () ব্যবহার করে বাইটে রূপান্তরিত করে।

যদি এটি একটি পূর্ণসংখ্যা হয় তবে অ্যারেটির আকারটি হবে এবং নাল বাইটের সাহায্যে আরম্ভ করা হবে।

যদি এটি বাফার ইন্টারফেসের সাথে সঙ্গতিপূর্ণ কোনও জিনিস হয় তবে বাইটস অ্যারে শুরু করার জন্য অবজেক্টের কেবল পঠনযোগ্য বাফারটি ব্যবহার করা হবে।

যদি এটি একটি পুনরাবৃত্তিযোগ্য হয় তবে এটি অবশ্যই 0 <= x <256 পরিসরের মধ্যে পূর্ণসংখ্যার পুনরাবৃত্ত হতে হবে, যা অ্যারের প্রাথমিক সামগ্রী হিসাবে ব্যবহৃত হয়।

একটি আর্গুমেন্ট ছাড়া, 0 আকারের একটি অ্যারে তৈরি করা হয়।

সুতরাং bytesকেবল একটি স্ট্রিং এনকোড করা ছাড়াও আরও অনেক কিছু করা যায়। এটি পাইথোনিক যে এটি আপনাকে কোনও ধরণের উত্স পরামিতি দিয়ে কনস্ট্রাক্টরকে কল করতে দেয়।

স্ট্রিং এনকোডিংয়ের জন্য, আমি মনে করি এটি some_string.encode(encoding)নির্মাণকারীর চেয়ে বেশি পাইথোনিক, কারণ এটি সর্বাধিক স্ব নথিভুক্ত - "এই স্ট্রিংটি নিন এবং এই এনকোডিং দিয়ে এটি এনকোড করুন" এর চেয়ে পরিষ্কার bytes(some_string, encoding)- আপনি যখন ব্যবহার করবেন তখন কোনও স্পষ্ট ক্রিয়া নেই কন্সট্রাকটর।

সম্পাদনা: আমি পাইথনের উত্স পরীক্ষা করেছিলাম। আপনি যদি সিপথনbytes ব্যবহারের জন্য একটি ইউনিকোড স্ট্রিংটি পাস করেন তবে এটি পাইউনিকোড_এএসইঙ্কোড স্ট্রিংকে কল করে যা এটি বাস্তবায়ন encode; সুতরাং আপনি যদি encodeনিজেকে কল করেন তবে আপনি কেবল মাত্র একটি ইন্ডিরিয়ারেশন এড়িয়ে যাচ্ছেন ।

এছাড়াও, সেরডালিসের মন্তব্য দেখুন - unicode_string.encode(encoding)এটি আরও বেশি পাইথোনিক কারণ এর বিপরীতটি রয়েছে byte_string.decode(encoding)এবং প্রতিসাম্য সুন্দর।


73
অজগর ডক্স থেকে ভাল যুক্তি এবং উদ্ধৃতি দেওয়ার জন্য +1। এছাড়াও unicode_string.encode(encoding)সঙ্গে চমত্কারভাবে সাথে মিলে যায় bytearray.decode(encoding)যখন আপনি আপনার স্ট্রিং ফেরত চাই।
সের্ডালিস

6
bytearrayআপনার যখন কোনও পরিবর্তনীয় বস্তুর প্রয়োজন হয় তখন ব্যবহৃত হয়। আপনি সহজ জন্য এটি প্রয়োজন হবে না strbytesধর্মান্তর।
hamstergene

8
@ ইউজেনহোমায়াকভ এর সাথে bytearrayডকস bytesবিবরণ না দেওয়ার ব্যতিরেকে কিছুই করার নেই , তারা কেবল "এটি একটি অপরিবর্তনীয় সংস্করণ bytearray" বলে তাই আমাকে সেখান থেকে উদ্ধৃতি দিতে হবে।
agf

1
থেকে মাত্র সতর্কতা নোট মধ্যে সংক্ষেপে পাইথন সম্পর্কে bytesচলুন একটি পূর্ণসংখ্যা আর্গুমেন্ট সহ একটি ফাংশন হিসাবে বাইট টাইপ ব্যবহার করছে:। ভি 2-তে এটি পূর্ণসংখ্যাটিকে (বাইট) স্ট্রিংয়ে রূপান্তরিত করে কারণ বাইটগুলি স্ট্রের জন্য একটি উপনাম হয়, এবং ভি 3-তে এটি নাল অক্ষরের সংখ্যার সমন্বিত একটি বাইটারেস্টিং প্রদান করে। সুতরাং, উদাহরণস্বরূপ, ভি 3 এক্সপ্রেশন বাইটের পরিবর্তে (6), সমান বি '\ x00' * 6 ব্যবহার করুন, যা প্রতিটি সংস্করণে নির্বিঘ্নে একইভাবে কাজ করে।
হোল্ডেনওয়েব

1
শুধু একটি নোট, যে যদি আপনি একটি স্ট্রিং বাইনারি ডেটা রূপান্তর করার চেষ্টা করছেন, তখন আপনি কিছু ব্যবহার সম্ভবত প্রয়োজন ও পছন্দ করবেন byte_string.decode('latin-1')যেমন utf-8সমগ্র পরিসীমা 0x00 0xFF করার জন্য (0-255), কাভার করে না পাইথন খুঁজে বার করো ডক্স জন্য অধিক তথ্য.
iggy12345

345

এটি যতটা ভাবা হয় তার চেয়ে সহজ:

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

37
তিনি এটি করতে জানেন, তিনি কেবল জিজ্ঞাসা করছেন কোন উপায়টি ভাল। প্রশ্নটি আবার পড়ুন।
agf

30
এফওয়াইআই: str.decode (বাইটস) আমার পক্ষে কাজ করেনি (পাইথন ৩.৩.৩ বলেছেন "টাইপ অবজেক্ট 'str' এর কোনও 'ডিকোড' নেই") আমি বাইটস ডেকোড () এর পরিবর্তে ব্যবহার করেছি
মাইক

6
@ মাইক: obj.method()সিনট্যাক্সের পরিবর্তে cls.method(obj)সিনট্যাক্স ব্যবহার করুন অর্থাত্‍, ব্যবহার করুন bytestring = unicode_text.encode(encoding)unicode_text = bytestring.decode(encoding)
jfs

2
... অর্থাত্ আপনি অযথা একটি আনবাউন্ড পদ্ধতি তৈরি করছেন, এবং তারপরে একে selfপ্রথম যুক্তি হিসাবে আখ্যায়িত করছেন
আন্তি হাপাল

2
@ কলবক্যানিয়ন প্রশ্ন ইতিমধ্যে এটি করার সঠিক উপায়টি দেখায় — encodeস্ট্রিংয়ের একটি আবদ্ধ পদ্ধতি হিসাবে কল । এই উত্তরটি পরামর্শ দেয় যে পরিবর্তে আপনার আনবাউন্ড পদ্ধতিতে কল করা উচিত এবং স্ট্রিংটি পাস করুন। উত্তরের একমাত্র নতুন তথ্য এবং এটি ভুল।
অবতরণ

144

একেবারে সবচেয়ে ভালো উপায় 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, অর্থ অভ্যন্তরীণ স্টোরেজটি ইতিমধ্যে ইউটিএফ -8 সংস্করণ, সুতরাং কোডকে সন্ধান করা মোটামুটি একমাত্র ব্যয়, এবং (খ) স্ট্রিংটি ছোট সুতরাং, আপনার যদি এনকোড করতে হয়, তবে এটি খুব বেশি পার্থক্য করে না। এটি দিয়ে চেষ্টা করুন, বলুন '\u00012345'*10000। উভয়ই আমার ল্যাপটপে 28.8us নেয়; অতিরিক্ত 50ns সম্ভবত গোলাকার ত্রুটিতে হারিয়ে গেছে। অবশ্যই এটি একটি চূড়ান্ত উদাহরণ — তবে 'abc'ঠিক বিপরীত দিকের মতো চরম।
23:22

@ বার্নার্ট সত্য, তবে তবুও, যুক্তিটিকে স্ট্রিং হিসাবে পাস করার কোনও কারণ নেই।
আন্তি হাপাল

এটি অনুসারে, ডিফল্ট যুক্তিগুলি সর্বদা জিনিসগুলি করার জন্য "একেবারে সেরা উপায়", তাই না? যদি সি কোড নিয়ে আলোচনা করা হয় তবে এই জাতীয় গতি বিশ্লেষণ সম্ভাব্য অতিরঞ্জিত মনে হবে। একটি ব্যাখ্যা করা ভাষায়, এটি আমাকে নির্বাক করে ফেলে।
হামিজাইল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.