স্ট্রিং আক্ষরিকের সামনে 'বি' চরিত্রটি কী করবে?


829

স্পষ্টতই, নিম্নলিখিতটি বৈধ বাক্য গঠন:

my_string = b'The string'

আমি জানতে চাই:

  1. bস্ট্রিংয়ের সামনে এই চরিত্রটির অর্থ কী?
  2. এটি ব্যবহারের প্রভাবগুলি কী কী?
  3. এটি ব্যবহার করার জন্য উপযুক্ত পরিস্থিতিগুলি কী কী?

আমি ঠিক এখানে এসও-তে একটি সম্পর্কিত প্রশ্ন পেয়েছি , তবে সেই প্রশ্নটি যদিও পিএইচপি সম্পর্কিত, এবং এটিতে বলা bহয়েছে যে স্ট্রিংটি বাইনারি হিসাবে চিহ্নিত করতে ব্যবহৃত হয়, ইউনিকোডের বিপরীতে, যা পিএইচপি <6 এর সংস্করণ থেকে কোডের সাথে সামঞ্জস্যপূর্ণ হওয়ার জন্য প্রয়োজনীয় ছিল , পিএইচপি 6 এ স্থানান্তরিত করার সময় 6 আমি পাইথনের ক্ষেত্রে এটি প্রযোজ্য বলে মনে করি না।

ইউনিকোড হিসাবে একটি স্ট্রিং নির্দিষ্ট করতে একই সিনট্যাক্সের একটি অক্ষর ব্যবহার সম্পর্কে পাইথন সাইটে আমি এই ডকুমেন্টেশনটি পেয়েছি u। দুর্ভাগ্যক্রমে, এটি দস্তাবেজের কোথাও বি চরিত্রের উল্লেখ করে না ।

এছাড়াও, কেবল কৌতূহলের বাইরে, এর চেয়ে আরও বেশি চিহ্ন রয়েছে bএবং uযেগুলি অন্যান্য জিনিসগুলি করে?

উত্তর:


415

পাইথন ২.x ডকুমেন্টেশনের উদ্ধৃতি দিতে :

পাইথন 2 এ 'বি' বা 'বি' এর উপসর্গ উপেক্ষা করা হয়; এটি নির্দেশ করে যে আক্ষরিকটি পাইথন 3 এ বাইটস আক্ষরিক হয়ে উঠতে হবে (উদাহরণস্বরূপ যখন কোড স্বয়ংক্রিয়ভাবে 2to3 দিয়ে রূপান্তরিত হয়)। একটি 'ইউ' বা 'বি' উপসর্গের পরে একটি 'আর' উপসর্গ হতে পারে।

পাইথন 3 ডকুমেন্টেশন পদ বলে:

বাইটস আক্ষরিকাগুলি সর্বদা 'খ' বা 'বি' দিয়ে উপস্থাপিত হয়; তারা স্ট্র টাইপের পরিবর্তে বাইট টাইপের একটি উদাহরণ তৈরি করে। এগুলিতে কেবল এএসসিআইআই অক্ষর থাকতে পারে; 128 বা তার বেশি সংখ্যার মান সহ বাইটগুলি অবশ্যই পলায়ন সহ প্রকাশ করতে হবে।


4
সুতরাং মনে হচ্ছে পাইথন <v3 কেবল এই অতিরিক্ত চরিত্রটিকে উপেক্ষা করবে। V3 এর ক্ষেত্রে কী হবে যেখানে আপনার কেবল স্ট্রিংয়ের বিপরীতে অ্যাব স্ট্রিং ব্যবহার করতে হবে?
জেসি ওয়েব

5
@ জিউয়েজ - যদি আপনি আসলে ইউনিকোড পলায়নের পরিবর্তে কোনও নির্দিষ্ট এনকোডিংয়ে একটি স্ট্রিং টাইপ করে থাকেন (যেমন, '' 32 u32e1 '' এর পরিবর্তে বি '\ xff \ xfe \ xe12')।
স্পষ্টত

7
আসলে, যদি আপনি আমদানি করেছেন unicode_literalsথেকে __future__, এই এই বিশেষ স্ট্রিং এর জন্য আচরণ (পাইথন 2.x এ) "বিপরীত" হবে
Romuald Brunet

33
উদ্ধৃত ডকুমেন্টেশনের চারপাশে আরও কিছু সরল ভাষার বিবরণ এটিকে আরও ভাল উত্তর দেবে আইএমএইচও
হ্যাক-আর

2
অন্যথায়, এটি ইতিমধ্যে বোঝে এমন কারও জন্য একটি উত্তর।
রাফায়েল আইং

675

পাইথন ৩.x প্রকারের মধ্যে স্পষ্ট পার্থক্য করে:

  • str= '...'আক্ষরিক = ইউনিকোড অক্ষরের একটি অনুক্রম (ইউটিএফ -16 বা ইউটিএফ -32, পাইথনটি কীভাবে সংকলিত হয়েছিল তার উপর নির্ভর করে)
  • bytes= b'...'আক্ষরিক = অক্টেটের ক্রম (0 এবং 255 এর মধ্যে পূর্ণসংখ্যা)

আপনি যদি জাভা বা সি # এর সাথে পরিচিত হন তবে strহিসাবে Stringএবং bytesহিসাবে চিন্তা করুন byte[]। আপনি এসকিউএল সাথে পরিচিত হন, তাহলে মনে strযেমন NVARCHARএবং bytesহিসাবে BINARYবা BLOB। যদি আপনি উইন্ডোজ রেজিস্ট্রির সাথে পরিচিত হন তবে strহিসাবে REG_SZএবং bytesহিসাবে মনে করুন REG_BINARY। আপনি যদি সি (++) এর সাথে পরিচিত হন, তবে আপনি যা শিখেছেন charএবং স্ট্রিংগুলি শিখেছেন তা সব ভুলে যান , কারণ একটি চরিত্র বাইট নয় । এই ধারণা দীর্ঘ অপ্রচলিত।

আপনি strযখন পাঠ্য উপস্থাপন করতে চান তখন আপনি ব্যবহার করুন।

print('שלום עולם')

আপনি bytesযখন স্ট্রকের মতো নিম্ন-স্তরের বাইনারি ডেটা উপস্থাপন করতে চান তখন আপনি ব্যবহার করুন ।

NaN = struct.unpack('>d', b'\xff\xf8\x00\x00\x00\x00\x00\x00')[0]

আপনি করতে পারেন এনকোড একটি strএকটি থেকে bytesঅবজেক্ট।

>>> '\uFEFF'.encode('UTF-8')
b'\xef\xbb\xbf'

এবং আপনি একটি bytesমধ্যে ডিকোড করতে পারেন str

>>> b'\xE2\x82\xAC'.decode('UTF-8')
'€'

তবে আপনি অবাধে দুটি ধরণের মিশ্রিত করতে পারবেন না।

>>> b'\xEF\xBB\xBF' + 'Text with a UTF-8 BOM'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't concat bytes to str

b'...'স্বরলিপি কিছুটা মধ্যে বিভ্রান্তিকর এটা 0x01-0x7F বাইট হেক্স সংখ্যার পরিবর্তে ASCII অক্ষর দিয়ে চিহ্নিত করা যাবে যে হয়।

>>> b'A' == b'\x41'
True

তবে আমার অবশ্যই জোর দিতে হবে, একটি চরিত্র বাইট নয়

>>> 'A' == b'A'
False

পাইথন ২.x

পাইথনের প্রাক-3.0 সংস্করণগুলিতে পাঠ্য এবং বাইনারি ডেটার মধ্যে এই জাতীয় পার্থক্যের অভাব রয়েছে। পরিবর্তে, সেখানে ছিল:

  • unicode= u'...'আক্ষরিক = ইউনিকোড অক্ষরের ক্রম = 3.xstr
  • str= '...'আক্ষরিক = বিভ্রান্ত বাইট / অক্ষরের ক্রম
    • সাধারণত পাঠ্য, কিছু অনির্দিষ্ট এনকোডিং এ এনকোড করা।
    • তবে struct.packআউটপুটের মতো বাইনারি ডেটা উপস্থাপন করতেও ব্যবহৃত হত ।

2.x-to-3.x রূপান্তরটি সহজ করার জন্য, পাঠ্য স্ট্রিংগুলি (যা 3-এ হওয়া উচিত) থেকে b'...'বাইনারি স্ট্রিং (যা bytes3.x হওয়া উচিত ) পৃথক করার জন্য আক্ষরিক সিনট্যাক্সটি পাইথন ২.6 এ ব্যাকপোর্ট করা হয়েছিল str.এক্স). bউপসর্গ 2.x কিছুই না, কিন্তু বলে 2to3স্ক্রিপ্ট এটা 3.x. একটি ইউনিকোড স্ট্রিং রূপান্তর করতে না

সুতরাং হ্যাঁ, b'...'পাইথনের আক্ষরিকের একই উদ্দেশ্য রয়েছে যা তারা পিএইচপি-তে করেন।

এছাড়াও, কৌতূহলের বাইরে, খ এবং ইউ এর চেয়ে আরও বেশি চিহ্ন রয়েছে যা অন্যান্য কাজ করে?

rউপসর্গ একটি কাঁচা স্ট্রিং তৈরি করে (যেমন, r'\t'একটি ব্যাকস্ল্যাশ + + হয় tপরিবর্তে একটি ট্যাব), এবং ট্রিপল কোট '''...'''বা """..."""বহু-লাইন স্ট্রিং লিটারেল অনুমতি দেয়।


2
ধন্যবাদ! আমি এই বাক্যগুলি পড়ার পরে এটি বুঝতে পেরেছিলাম: "2.x-to-3.x রূপান্তরটি সহজ করার জন্য, খ '...' আক্ষরিক সিনট্যাক্সটি পাইথন ২. to এ ব্যাকপোর্ট করা হয়েছিল, যাতে বাইনারি স্ট্রিংগুলিকে পৃথক করা যায় (যা হওয়া উচিত) টেক্সট স্ট্রিং থেকে 3.x এ বাইট করুন (যা 3.x তে স্টার হওয়া উচিত)। বি উপসর্গটি 2.x তে কিছুই করেনা, তবে 2to3 স্ক্রিপ্টকে 3.x এ ইউনিকোড স্ট্রিংতে রূপান্তর না করতে বলে। "
tommy.carstensen

4
'A' == b'A' --> Falseচেক সত্যিই এটা পরিষ্কার করে তোলে। এটির বাকীটি দুর্দান্ত, তবে আমি এখনও সঠিকভাবে বুঝতে পারি নি যে একটি বাইট স্ট্রিং আসলে পাঠ্য নয়।
ওয়াইল্ডকার্ড

12
'שלום עולם' == 'hello world'
এলি

12
এটি গ্রহণযোগ্য উত্তরের চেয়ে অনেক বেশি স্পষ্ট যা কেবলমাত্র ডকুমেন্টেশনের উদ্ধৃতি দিচ্ছে। আমার কাছে ডকুমেন্টেশনের কোনও অর্থ নেই তাই ডকুমেন্টেশনে আরও প্রসঙ্গ সরবরাহ করা দুর্দান্ত। ধন্যবাদ!
রেয়রিং

2
বি "কিছু স্ট্রিং"। ডিকোড ('ইউটিএফ -8'), আমি বিশ্বাস করি যে অনেকেই সেই রেখাটি খুঁজছেন
মারভিন থোবজেন

22

বি একটি বাইট স্ট্রিং বোঝায়।

বাইটস হ'ল আসল ডেটা। স্ট্রিংগুলি একটি বিমূর্ততা।

আপনার যদি মাল্টি-ক্যারেক্টার স্ট্রিং অবজেক্ট থাকে এবং আপনি একটি একক অক্ষর গ্রহণ করেন তবে এটি একটি স্ট্রিং হবে এবং এটি এনকোডিংয়ের উপর নির্ভর করে আকারে 1 বাইটের বেশি হতে পারে।

যদি বাইট স্ট্রিং সহ 1 বাইট নেয়, আপনি 0-255 থেকে একক 8-বিট মান পাবেন এবং এনকোডিংয়ের কারণে those অক্ষরগুলি> 1 বাইট থাকলে এটি একটি সম্পূর্ণ চরিত্রের প্রতিনিধিত্ব করতে পারে না।

টিবিএইচ আমি বাইটগুলি ব্যবহারের জন্য নির্দিষ্ট কোনও নিম্ন স্তরের কারণ না থাকলে আমি স্ট্রিংগুলি ব্যবহার করব।


16

সার্ভার দিক থেকে, যদি আমরা কোনও প্রতিক্রিয়া প্রেরণ করি তবে এটি বাইট টাইপের আকারে প্রেরণ করা হবে, সুতরাং এটি ক্লায়েন্ট হিসাবে প্রদর্শিত হবে b'Response from server'

যাতে b'....'সহজেই নীচের কোডটি ব্যবহার থেকে মুক্তি পান :

সার্ভার ফাইল:

stri="Response from server"    
c.send(stri.encode())

ক্লায়েন্ট ফাইল:

print(s.recv(1024).decode())

তারপরে এটি মুদ্রণ করবে Response from server


1
এটি জেসি ওয়েব যে প্রশ্নটি করেছে তা ব্যাখ্যা করে না!
চন্দ্র কণ্ঠ

আমি বলছিলাম যে এনকোড এবং ডিকোড পদ্ধতিগুলি ব্যবহার না করে স্ট্রিং আউটপুটটি বি'র সাথে উপস্থাপিত হবে কারণ পাইথন একে স্ট্রিং টাইপের পরিবর্তে বাইট টাইপ হিসাবে গ্রহণ করবে f আপনি বি'র মতো আউটপুট পেতে না চান ... 'উপরেরটি এটি ব্যবহার করুন এটি। আপনি কি বুঝতে পারলেন না?
নানি চিন্তায়

আসলে এটিই যে প্রশ্নের জিজ্ঞাসা করা হয়েছিল তার শিরোনামের সঠিক উত্তর : প্রশ্ন: "বি'এক্স 'কী করে?" উত্তর: "এটি 'x'.encode () করে" এটি আক্ষরিকভাবে এটি করে। বাকি প্রশ্নটি এর চেয়ে আরও অনেক কিছু জানতে চেয়েছিল, তবে শিরোনামের উত্তর দেওয়া হয়েছে।
মাইকেল এরিকসন

10

এখানে একটি উদাহরণ যেখানে অভাবে এর bএকটি নিক্ষেপ করা হবে TypeErrorপাইথন 3.x মধ্যে ব্যতিক্রম

>>> f=open("new", "wb")
>>> f.write("Hello Python!")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' does not support the buffer interface

একটি bউপসর্গ যুক্ত করা সমস্যার সমাধান করবে।


9

এটি এটিকে bytesআক্ষরিক (বা str২.x এ) রূপান্তরিত করে এবং ২.6+ এর জন্য বৈধ।

rউপসর্গ কারণ "uninterpreted" করা ব্যাকস্ল্যাশ (উপেক্ষিত না হয়, এবং পার্থক্য আছে ব্যাপার)।


আইসের উত্তরে উদ্ধৃত ডকুমেন্টেশন অনুসারে এটি ভুল বলে মনে হচ্ছে; খ পাইথন সংস্করণে 3 ছাড়া অন্য উপেক্ষা করা হবে
জেসি ওয়েব

2
এটি যে strকোনও উপায়ে 2.x এ হবে, সুতরাং এটি উপেক্ষা করা যায় এমনটি বলা যেতে পারে। আপনি যখন মডিউলটি unicode_literalsথেকে আমদানি করবেন তখন পার্থক্যটি গুরুত্বপূর্ণ __future__
ইগনাসিও ওয়াজকেজ-আব্রামস

6

অন্যেরা যা বলেছেন তা ছাড়াও, নোট করুন যে ইউনিকোডের একটি একক অক্ষরে একাধিক বাইট থাকতে পারে

ইউনিকোড যেভাবে কাজ করে তা হ'ল এটি পুরানো এএসসিআইআই ফর্ম্যাটটি নিয়েছে (--বিট কোড যা 0XXX xxxx এর মতো দেখাচ্ছে) এবং মাল্টি-বাইট সিকোয়েন্স যুক্ত করেছে যেখানে সমস্ত বাইট 1 (1xxx xxxx) দিয়ে শুরু করে ASCII এর বাইরে অক্ষরের প্রতিনিধিত্ব করে যাতে ইউনিকোড পিছনের দিকে চলে যায় -এসসিআইআই এর সাথে সামঞ্জস্যপূর্ণ

>>> len('Öl')  # German word for 'oil' with 2 characters
2
>>> 'Öl'.encode('UTF-8')  # convert str to bytes 
b'\xc3\x96l'
>>> len('Öl'.encode('UTF-8'))  # 3 bytes encode 2 characters !
3

2

আপনি এটি অভিধানে রূপান্তর করতে JSON ব্যবহার করতে পারেন

import json
data = b'{"key":"value"}'
print(json.loads(data))

{"প্রকৃত মূল্য"}


ফ্লাস্ক:

এটি ফ্লাস্কের একটি উদাহরণ। টার্মিনাল লাইনে এটি চালান:

import requests
requests.post(url='http://localhost(example)/',json={'key':'value'})

ফ্লাস্ক / রুটস.পিতে

@app.route('/', methods=['POST'])
def api_script_add():
    print(request.data) # --> b'{"hi":"Hello"}'
    print(json.loads(request.data))
return json.loads(request.data)

{'প্রকৃত মূল্য'}

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.