TypeError: পাইথন 3-এ কোনও ফাইল লেখার সময় বাইট-এর মতো অবজেক্টের প্রয়োজন হয় 'স্ট্রিং' নয়


590

আমি খুব সম্প্রতি পাই 3.5 তে মাইগ্রেশন করেছি। এই কোডটি পাইথন ২.7 এ সঠিকভাবে কাজ করছিল:

with open(fname, 'rb') as f:
    lines = [x.strip() for x in f.readlines()]

for line in lines:
    tmp = line.strip().lower()
    if 'some-pattern' in tmp: continue
    # ... code

3.5 এ উন্নীত করার পরে, আমি এইটি পেয়ে যাচ্ছি:

TypeError: a bytes-like object is required, not 'str'

শেষ লাইনে ত্রুটি (প্যাটার্ন অনুসন্ধান কোড)।

আমি .decode()বিবৃতিটির দু'দিকে ফাংশনটি ব্যবহার করার চেষ্টা করেছি, চেষ্টা করেছি :

if tmp.find('some-pattern') != -1: continue

- কোন লাভ হয়নি।

আমি প্রায় সমস্ত 2: 3 টি সমস্যা দ্রুত সমাধান করতে সক্ষম হয়েছি, তবে এই ছোট্ট বিবৃতিটি আমাকে তাড়িত করছে।


11
আপনি কেন বাইনারি মোডে ফাইলটি খুলছেন কিন্তু এটি পাঠ্য হিসাবে বিবেচনা করছেন?
মার্টিজন পিটারস

4
ওপেন মোড ফাইলটি চিহ্নিত করার জন্য @ মার্তিজন পিপিটার্সকে ধন্যবাদ! এটি টেক্সট-মোডে পরিবর্তন করার ফলে সমস্যাটি সমাধান হয়েছে ... কোডটি পাইপেকেতে বহু বছর ধরে নির্ভরযোগ্যভাবে কাজ করেছিল যদিও ...
মাসুরুর

4
@ মাসুরুর দেখুন: পাইথন.আর.দেব
রবার্তো

10
আমি এখানেও আমার মুখোমুখি হচ্ছি যেখানে আমার একটি অনুরোধ আছে result = requests.getএবং আমি চেষ্টা করছি x = result.content.split("\n")। আমি ত্রুটি বার্তায় কিছুটা বিভ্রান্ত হয়েছি কারণ এটি মনে হচ্ছে এটি result.contentএকটি স্ট্রিং এবং .split()বাইটস জাতীয় বস্তুর প্রয়োজন আছে .. ?? ("বাইটের মতো অবজেক্টের প্রয়োজন, '

উত্তর:


553

আপনি ফাইলটি বাইনারি মোডে খুললেন:

with open(fname, 'rb') as f:

এর অর্থ ফাইল থেকে পড়া সমস্ত ডেটা bytesঅবজেক্ট হিসাবে ফিরে আসে , না str। তারপরে আপনি একটি ধারন পরীক্ষায় একটি স্ট্রিং ব্যবহার করতে পারবেন না:

if 'some-pattern' in tmp: continue

পরিবর্তে bytesআপনাকে পরীক্ষা করতে কোনও অবজেক্ট ব্যবহার করতে tmpহবে:

if b'some-pattern' in tmp: continue

অথবা 'rb'মোডটি প্রতিস্থাপনের পরিবর্তে ফাইলটিকে পাঠ্য ফাইল হিসাবে খুলুন 'r'


12
আপনি যদি পিপিএল-এর সাথে লিঙ্কযুক্ত বিভিন্ন নথিগুলি দেখে থাকেন তবে আপনি দেখতে পাবেন যে পাই 2-তে সমস্ত কিছু "কাজ করেছে" কারণ ডিফল্ট স্ট্রিংগুলি বাইট ছিল যেখানে পাই 3-তে, ডিফল্ট স্ট্রিংগুলি ইউনিকোড, মানে যে কোনও সময় আপনি আই / ও করছেন, ESP। নেটওয়ার্কিং, বাইট স্ট্রিংগুলি স্ট্যান্ডার্ড, সুতরাং আপনাকে অবশ্যই বি / ডাব্লু ইউনিকোড এবং বাইটস স্ট্রিংগুলি সরিয়ে নিতে শিখতে হবে (এন / ডিকোড)। ফাইলগুলির জন্য, এখন আমাদের "r" বনাম "আরবি" রয়েছে (এবং 'ডাব্লু' এবং 'এ' এর জন্য) পার্থক্যটি সহায়তা করতে পারে।
ওয়েলস্কি

3
@wescpy: পাইথন 2 আছে 'r'বনাম 'rb' খুব , বাইনারি এবং টেক্সট ফাইল আচরণে মধ্যে স্যুইচ (অনুবাদ নতুন লাইন মত এবং নির্দিষ্ট প্ল্যাটফর্মের উপর কিভাবে ফাইলের শেষে মার্কার চিকিত্সা করা হয়)। যে ioলাইব্রেরী (পাইথন 2 পাইথন 3 ডিফল্ট ইনপুট / আউটপুট কার্যকারিতা কিন্তু প্রাপ্তিসাধ্য প্রদানের) এখন এছাড়াও decodes ডিফল্টরূপে পাঠ্য ফাইল বাস্তব পরিবর্তন।
মার্টিজন পিটারস

2
@ মার্তিজজনপিটারস: হ্যাঁ, একমত হয়েছেন। ২.x-তে, আমি কেবল 'b'ডস / উইন্ডোজে বাইনারি ফাইলগুলির সাথে কাজ করার সময় পতাকাটি ব্যবহার করি (যেমন বাইনারিটি পসিক্স ডিফল্ট হয়)। এটি ভাল যে ioফাইল অ্যাক্সেসের জন্য 3.x ব্যবহার করার সময় দ্বৈত উদ্দেশ্য রয়েছে ।
ওয়েডস্কি

207

আপনি ব্যবহার করে আপনার স্ট্রিং এনকোড করতে পারেন .encode()

উদাহরণ:

'Hello World'.encode()

48

এটি ইতিমধ্যে উল্লেখ করা হয়েছে এর মতো, আপনি ফাইলটি বাইনারি মোডে পড়ছেন এবং তারপরে বাইটগুলির একটি তালিকা তৈরি করছেন। আপনার জন্য নিম্নলিখিতলুপের আপনি স্ট্রিংকে বাইটের সাথে তুলনা করছেন এবং কোডটি ব্যর্থ হচ্ছে।

তালিকায় যুক্ত করার সময় বাইটগুলি ডিকোড করার কাজ করা উচিত। পরিবর্তিত কোডটি নীচে দেখতে হবে:

with open(fname, 'rb') as f:
    lines = [x.decode('utf8').strip() for x in f.readlines()]

বাইটস টাইপটি পাইথন 3 এ প্রবর্তিত হয়েছিল এবং সে কারণেই আপনার কোডটি পাইথন 2 এ কাজ করে Py পাইথন 2 তে বাইটগুলির জন্য কোনও ডেটা টাইপ ছিল না:

>>> s=bytes('hello')
>>> type(s)
<type 'str'>

25

আপনাকে ডাব্লু ডাব্লু থেকে ডাব্লুতে পরিবর্তন করতে হবে:

def __init__(self):
    self.myCsv = csv.writer(open('Item.csv', 'wb')) 
    self.myCsv.writerow(['title', 'link'])

প্রতি

def __init__(self):
    self.myCsv = csv.writer(open('Item.csv', 'w'))
    self.myCsv.writerow(['title', 'link'])

এটি পরিবর্তন করার পরে, ত্রুটিটি অদৃশ্য হয়ে যায়, তবে আপনি ফাইলটিতে লিখতে পারবেন না (আমার ক্ষেত্রে)। সুতরাং সব পরে, আমার একটি উত্তর নেই?

উত্স: remove এম অপসারণ করার পদ্ধতি

'আরবি' তে পরিবর্তন করা আমার অন্যান্য ত্রুটি নিয়ে আসে: io.UnsupportedOperation: লিখুন


15

এই ছোট উদাহরণের জন্য: সকেট আমদানি করুন

mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('www.py4inf.com', 80))
mysock.send(**b**'GET http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n')

while True:
    data = mysock.recv(512)
    if ( len(data) < 1 ) :
        break
    print (data);

mysock.close()

'GET http://www.py4inf.com/code/romeo.txt HTTP / 1.0 \ n before n' এর আগে "বি" যুক্ত করা আমার সমস্যার সমাধান করেছে


11

একক উদ্ধৃতিতে দেওয়া হার্ডকোডযুক্ত স্ট্রিং মান সহ এনকোড () ফাংশন ব্যবহার করুন।

উদা:

file.write(answers[i] + '\n'.encode())

অথবা

line.split(' +++$+++ '.encode())

8

আপনি ফাইলটি বাইনারি মোডে খুললেন:

নিম্নলিখিত কোডটি একটি টাইপরর ফেলে দেবে: বাইট-এর মতো অবজেক্টটি প্রয়োজন, 'স্ট্র' নয়।

for line in lines:
    print(type(line))# <class 'bytes'>
    if 'substring' in line:
       print('success')

নিম্নলিখিত কোডটি কাজ করবে - আপনাকে ডিকোড () ফাংশনটি ব্যবহার করতে হবে:

for line in lines:
    line = line.decode()
    print(type(line))# <class 'str'>
    if 'substring' in line:
       print('success')

4

আপনার ফাইলটি পাঠ্য হিসাবে খোলার চেষ্টা করবেন না কেন?

with open(fname, 'rt') as f:
    lines = [x.strip() for x in f.readlines()]

অতিরিক্তভাবে এখানে সরকারী পৃষ্ঠায় অজগর 3.x এর লিঙ্ক রয়েছে: https://docs.python.org/3/library/io.html এবং এটি উন্মুক্ত ফাংশন: https://docs.python.org/3 /library/functions.html#open

আপনি যদি সত্যিই এটি বাইনারি হিসাবে হ্যান্ডেল করার চেষ্টা করছেন তবে আপনার স্ট্রিংটিকে এনকোডিং করার বিষয়টি বিবেচনা করুন।


1

যখন আমি একটি চর (বা স্ট্রিং) এ রূপান্তর করার চেষ্টা করছিলাম তখন আমি এই ত্রুটিটি পেয়েছি bytes, পাইথন ২.7 সহ কোডটি এমন কিছু ছিল:

# -*- coding: utf-8 -*-
print( bytes('ò') )

এটি পাইথনের 2.7 এর পথইউনিকোড চরগুলি নিয়ে কাজ করার সময় ।

এটি পাইথন ৩.6 এর সাথে কাজ করবে না, যেহেতু bytesএনকোডিংয়ের জন্য অতিরিক্ত যুক্তি প্রয়োজন, তবে এটি কিছুটা জটিল হতে পারে, কারণ বিভিন্ন এনকোডিংয়ের ফলে বিভিন্ন ফলাফল আউটপুট পেতে পারে:

print( bytes('ò', 'iso_8859_1') ) # prints: b'\xf2'
print( bytes('ò', 'utf-8') ) # prints: b'\xc3\xb2'

আমার ক্ষেত্রে আমাকে ব্যবহার করতে হয়েছিল iso_8859_1 সমস্যাটি সমাধানের জন্য বাইটগুলি এনকোড করার সময় করতে হয়েছিল।

আশা করি এটি কাউকে সাহায্য করবে।

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