TypeError: 'str' বাফার ইন্টারফেসটি সমর্থন করে না


267
plaintext = input("Please enter the text you want to compress")
filename = input("Please enter the desired filename")
with gzip.open(filename + ".gz", "wb") as outfile:
    outfile.write(plaintext) 

উপরের পাইথন কোডটি আমাকে নিম্নলিখিত ত্রুটি দিচ্ছে:

Traceback (most recent call last):
  File "C:/Users/Ankur Gupta/Desktop/Python_works/gzip_work1.py", line 33, in <module>
    compress_string()
  File "C:/Users/Ankur Gupta/Desktop/Python_works/gzip_work1.py", line 15, in compress_string
    outfile.write(plaintext)
  File "C:\Python32\lib\gzip.py", line 312, in write
    self.crc = zlib.crc32(data, self.crc) & 0xffffffff
TypeError: 'str' does not support the buffer interface

1
@ মাইকপেনিংটন: দয়া করে ব্যাখ্যা করুন কেন পাঠ্য সংক্ষেপণ কার্যকর নয়?
গ্যালিনেট

উত্তর:


295

আপনি যদি stringপাইথন 3 এক্স ব্যবহার করেন তবে পাইথন ২.x এর মতো একই ধরনের নয়, আপনাকে অবশ্যই এটি বাইটে ফেলে দিতে হবে (এটি এনকোড করুন)।

plaintext = input("Please enter the text you want to compress")
filename = input("Please enter the desired filename")
with gzip.open(filename + ".gz", "wb") as outfile:
    outfile.write(bytes(plaintext, 'UTF-8'))

এছাড়াও পরিবর্তনশীল নামগুলি যেমন মডিউল বা ফাংশনের নামগুলি ব্যবহার করবেন না stringবা ব্যবহার করবেন না file

টম @ সম্পাদনা করুন

হ্যাঁ, নন-এএসসিআইআই পাঠ্যও সংকুচিত / সঙ্কোচিত। আমি ইউটিএফ -8 এনকোডিং সহ পোলিশ বর্ণগুলি ব্যবহার করি:

plaintext = 'Polish text: ąćęłńóśźżĄĆĘŁŃÓŚŹŻ'
filename = 'foo.gz'
with gzip.open(filename, 'wb') as outfile:
    outfile.write(bytes(plaintext, 'UTF-8'))
with gzip.open(filename, 'r') as infile:
    outfile_content = infile.read().decode('UTF-8')
print(outfile_content)

এটা ঠিক যে এটি স্থির; মূল কোডটি আমার জন্য ৩.১ এর অধীনে কাজ করেছে এবং ডক্সের নমুনা কোডটিও স্পষ্টভাবে এনকোড করে না। আপনি যদি এটি ASCII বিহীন পাঠ্যে ব্যবহার করেন তবে বন্দুকদ্বারটি কী তা সঙ্কুচিত করে? আমি একটি ত্রুটি পেয়েছি।
টম জাইচ

আমি ইউনিকোড হিন্দিতে আমার নাম টাইপ করেছি এবং এটি gzip এ সফলভাবে সংকুচিত হয়েছিল। আমি পাইথন ৩.২ ব্যবহার করছি
ফিউচার কিং

@ টম জাইচ: সম্ভবত ৩.২-র পরিবর্তনের সাথে কিছু আছে: ডকস.পাইথন.আর.দেব
৩.২.এইচটিএমএল

আমি এটি অ্যাক্টিভেট পাইথন 3.1 এবং 3.2 দিয়ে পরীক্ষা করেছি। আমার মেশিনে এটি দুটিতেই কাজ করে।
মিশা নিক্লাস

1
ফাইল সংকোচনের জন্য আপনাকে বাইনারি মোডে সর্বদা ইনপুটটি খুলতে হবে: আপনাকে পরে ফাইলটি সঙ্কুচিত করতে এবং ঠিক একই সামগ্রী পেতে সক্ষম হওয়া দরকার get ইউনিকোড ( str) এবং পিছনে রূপান্তর করা অপ্রয়োজনীয়, এবং ইনপুট এবং আউটপুটটির মধ্যে ডিকোডিং ত্রুটি বা অমিল risks
অ্যালেক্সিস

96

এই সমস্যার আরও সহজ সমাধান রয়েছে।

tআপনার মোডে কেবল একটি যুক্ত করা দরকার যাতে এটি হয়ে যায় wt। এটি পাইথনকে পাঠ্য ফাইল হিসাবে ফাইলটি খুলতে এবং বাইনারি হিসাবে তৈরি করে causes তাহলে সবকিছু ঠিক কাজ করবে work

সম্পূর্ণ প্রোগ্রাম এটি হয়ে যায়:

plaintext = input("Please enter the text you want to compress")
filename = input("Please enter the desired filename")
with gzip.open(filename + ".gz", "wt") as outfile:
    outfile.write(plaintext)

এটি কি পাইথন 2 এ কাজ করে? পাইথন 2 এবং পাইথন 3 এ কোডটি কাজ করার কোনও উপায় হতে পারে?
Loïc Faure-Lacroix

বাহ, মানুষ আপনি ভাল! ধন্যবাদ! আমি আপনাকে ভোট দিন। এটি গ্রহণযোগ্য উত্তর হওয়া উচিত :))
লক

15
"টি" যুক্ত করার ফলে পার্শ্ব প্রতিক্রিয়া হতে পারে। উইন্ডোজ ফাইলগুলিতে পাঠ্য হিসাবে এনকোড করা ফাইলগুলিতে নতুন লাইনের ("\ n") থাকবে সিআরএলএফ ("\ r \ n") তে রূপান্তরিত।
বিটওয়াইম্যান

42

আপনি কিছু এনকোডিংয়ে কোনও রূপান্তর ছাড়াই বাইটগুলিতে পাইথন 3 'স্ট্রিং' সিরিয়ালিয়াল করতে পারবেন না।

outfile.write(plaintext.encode('utf-8'))

সম্ভবত আপনি কি চান। এছাড়াও এটি অজগর 2.x এবং 3.x উভয়ের জন্য কাজ করে।


28

পাইথন ৩.x এর জন্য আপনি নিজের পাঠ্যকে কাঁচা বাইটে রূপান্তর করতে পারেন:

bytes("my data", "encoding")

উদাহরণ স্বরূপ:

bytes("attack at dawn", "utf-8")

প্রত্যাশিত বস্তুটি কাজ করবে outfile.write


9

পাই 2 থেকে পাই 3 এ স্যুইচ করার সময় এই সমস্যাটি সাধারণত দেখা দেয় occurs পাই 2 plaintextতে একটি স্ট্রিং এবং বাইট অ্যারের প্রকার উভয়ই । Py3 সালে plaintextমাত্র নয় স্ট্রিং এবং পদ্ধতি outfile.write()আসলে একটি লাগে বাইট অ্যারের যখন outfileবাইনারি মোডে খুলতে হয়, তাই একটি ব্যতিক্রম উত্থাপিত হয়। plaintext.encode('utf-8')সমস্যা সমাধানের জন্য ইনপুটটি পরিবর্তন করুন । যদি এটি আপনাকে বিরক্ত করে তবে পড়ুন।

Py2 সালে file.write জন্য ঘোষণা করেছেন এটা মনে হচ্ছে আপনি একটি স্ট্রিং পাস: file.write(str)। আসলে আপনি যদি একটি বাইট অ্যারের মধ্যে ক্ষণস্থায়ী হয়, আপনি ভালো ঘোষণা পড়া হওয়া উচিত ছিল: file.write(bytes)। আপনি এটা এই সমস্যা সহজ মত পড়তে পারেন, file.write(bytes)প্রয়োজন একটি বাইট পেতে ধরন এবং py3 মধ্যে বাইট একটি আউট Str আপনি এটা রূপান্তর:

py3>> outfile.write(plaintext.encode('utf-8'))

পিআই 2 ডক্স ঘোষিত কেন file.writeস্ট্রিং নিয়েছে? ভাল py2 এ ঘোষণাপত্রের পার্থক্য কোন বিষয় নয় কারণ:

py2>> str==bytes         #str and bytes aliased a single hybrid class in py2
True

পাই 2 এর স্ট্র-বাইটস ক্লাসে এমন পদ্ধতি / কনস্ট্রাক্টর রয়েছে যা এটি কিছু উপায়ে স্ট্রিং ক্লাসের মতো আচরণ করে এবং অন্যগুলিতে বাইট অ্যারে ক্লাস করে। file.writeএটা কি সুবিধাজনক নয় ?:

py2>> plaintext='my string literal'
py2>> type(plaintext)
str                              #is it a string or is it a byte array? it's both!

py2>> outfile.write(plaintext)   #can use plaintext as a byte array

পাই 3 কেন এই দুর্দান্ত সিস্টেমটি ভেঙে দিয়েছে? ওয়েল কারণ পাই 2 ইন বেসিক স্ট্রিং ফাংশনগুলি সারা বিশ্বে কাজ করে না। অ-এসকিআইআই অক্ষর দিয়ে কোনও শব্দের দৈর্ঘ্য পরিমাপ করবেন?

py2>> len('¡no')        #length of string=3, length of UTF-8 byte array=4, since with variable len encoding the non-ASCII chars = 2-6 bytes
4                       #always gives bytes.len not str.len

এই সমস্ত সময় আপনি ভেবেছিলেন আপনি পাই 2 তে স্ট্রিংয়ের লেন জিজ্ঞাসা করছেন , আপনি এনকোডিং থেকে বাইট অ্যারের দৈর্ঘ্য পাচ্ছেন। দ্ব্যর্থতা ক্লাসগুলির সাথে সেই অস্পষ্টতাই মূল সমস্যা। আপনি কোন পদ্ধতি কলের কোন সংস্করণটি প্রয়োগ করেন?

তারপরে সুসংবাদটি হ'ল পাই 3 এই সমস্যাটি সমাধান করে। এটা তোলে disentangles Str এবং বাইট ক্লাস। Str বর্গ হয়েছে স্ট্রিং মত পদ্ধতি, পৃথক বাইট বর্গ বাইট অ্যারের পদ্ধতি রয়েছে:

py3>> len('¡ok')       #string
3
py3>> len('¡ok'.encode('utf-8'))     #bytes
4

আশা করি এটি জানার ফলে বিষয়টি ডি-মাইটিসিভ করতে সহায়তা করে এবং মাইগ্রেশন ব্যথা সহ্য করতে কিছুটা সহজ করে তোলে।


4
>>> s = bytes("s","utf-8")
>>> print(s)
b's'
>>> s = s.decode("utf-8")
>>> print(s)
s

বিরক্তিকর 'বি' চরিত্রটি মুছে ফেলার ক্ষেত্রে যদি আপনার পক্ষে দরকারী হয় তবে যদি কেউ ভাল ধারণা পেয়ে থাকেন তবে দয়া করে আমাকে পরামর্শ দিন বা এখানে যে কোনও সময় আমাকে সম্পাদনা করতে নির্দ্বিধায় পড়ুন I আমি শুধু নবাগত


আপনি s.encode('utf-8')এটি s.decode('utf-8')প্রতিস্থাপন হিসাবে যেমন s = bytes("s", "utf-8")
পাইথোনিক

4

জন্য Djangodjango.test.TestCaseইউনিট টেস্টিং, আমি আমার পরিবর্তিত Python2 শব্দবিন্যাস:

def test_view(self):
    response = self.client.get(reverse('myview'))
    self.assertIn(str(self.obj.id), response.content)
    ...

পাইথন 3 .decode('utf8') সিনট্যাক্সটি ব্যবহার করতে :

def test_view(self):
    response = self.client.get(reverse('myview'))
    self.assertIn(str(self.obj.id), response.content.decode('utf8'))
    ...
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.