पायथन 3 में स्ट्रिंग


473

मैं पायथन 3.2.1 का उपयोग कर रहा हूं और मैं StringIOमॉड्यूल आयात नहीं कर सकता । मैं का उपयोग करें io.StringIOऔर यह काम करता है, लेकिन मैं के साथ उपयोग नहीं कर सकते numpyहै genfromtxtइस तरह:

x="1 3\n 4.5 8"        
numpy.genfromtxt(io.StringIO(x))

मुझे निम्नलिखित त्रुटि मिलती है:

TypeError: Can't convert 'bytes' object to str implicitly  

और जब मैं लिखता हूं तो import StringIOयह कहता है

ImportError: No module named 'StringIO'

जवाबों:


771

जब मैं आयात स्ट्रिंग लिखता हूं तो यह कहता है कि ऐसा कोई मॉड्यूल नहीं है।

से नया क्या है में अजगर 3.0 :

StringIOऔर cStringIOमॉड्यूल हट जाते हैं। इसके बजाय, io मॉड्यूल आयात करें और क्रमशः पाठ और डेटा के लिए io.StringIOया उपयोग करें io.BytesIO


पायथन 3 (कैविएट एम्प्टर) में काम करने के लिए कुछ पायथन 2 कोड को ठीक करने की संभवतः एक उपयोगी विधि:

try:
    from StringIO import StringIO ## for Python 2
except ImportError:
    from io import StringIO ## for Python 3

नोट: यह उदाहरण प्रश्न के मुख्य मुद्दे के लिए स्पर्शोन्मुख हो सकता है और केवल इस बात पर विचार करने के लिए कुछ के रूप में शामिल किया जाता है कि जब लापता StringIOमॉड्यूल को उदारतापूर्वक संबोधित किया जाए । संदेश के अधिक प्रत्यक्ष समाधान के लिए TypeError: Can't convert 'bytes' object to str implicitly, इस उत्तर को देखें ।


13
इनका उल्लेख करने वाले शब्द समान नहीं हैं, इसलिए TypeErrorयदि आप अलगाव में यह परिवर्तन करते हैं, तो आप s (स्ट्रिंग तर्क अपेक्षित, 'बाइट्स') प्राप्त कर सकते हैं। आपको अजगर 3 में बाइट्स और स्ट्र (यूनिकोड) को ध्यान से भेदने की आवश्यकता है
एंडी हेडन

7
मेरे जैसे नए लोगों के लिए: io आयात से स्ट्रिंग स्ट्रिंगियो का अर्थ है कि आप इसे स्ट्रिंग () के रूप में कहते हैं, न कि io.StringIO ()।
नूमेनन

11
वास्तव में पायथन 2 और 3 के साथ कैसे संगत किया जा सकता है: बसfrom io import StringIO
ओलेह प्रिनपिन

8
इस अजगर में numpy.genfromtxt () के लिए SIMPLY गलत है 3. रोमन Shapovalov से जवाब देखें।
बिल हुआंग

2
@ नोबर: बाद वाला। मूल प्रश्न अजगर 3.x का उपयोग करता है, जिसमें से मॉड्यूल StringIOचला गया है और from io import BytesIOइसके बजाय लागू किया जाना चाहिए। अजगर 3.5 पर अपना परीक्षण किया @ pyDev + win7 x64। कृपया मुझे बताएं कि क्या मैं गलत धन्यवाद था।
बिल हुआंग



24

आपके प्रश्न के लिए ओपी, और आपके उत्तर के लिए रोमन धन्यवाद। मुझे इसे खोजने के लिए थोड़ी खोज करनी पड़ी; मुझे आशा है कि निम्नलिखित दूसरों की मदद करता है।

पायथन 2.7

देखें: https://docs.scipy.org/doc/numpy/user/basics.io.genfreetom.html

import numpy as np
from StringIO import StringIO

data = "1, abc , 2\n 3, xxx, 4"

print type(data)
"""
<type 'str'>
"""

print '\n', np.genfromtxt(StringIO(data), delimiter=",", dtype="|S3", autostrip=True)
"""
[['1' 'abc' '2']
 ['3' 'xxx' '4']]
"""

print '\n', type(data)
"""
<type 'str'>
"""

print '\n', np.genfromtxt(StringIO(data), delimiter=",", autostrip=True)
"""
[[  1.  nan   2.]
 [  3.  nan   4.]]
"""

पायथन 3.5:

import numpy as np
from io import StringIO
import io

data = "1, abc , 2\n 3, xxx, 4"
#print(data)
"""
1, abc , 2
 3, xxx, 4
"""

#print(type(data))
"""
<class 'str'>
"""

#np.genfromtxt(StringIO(data), delimiter=",", autostrip=True)
# TypeError: Can't convert 'bytes' object to str implicitly

print('\n')
print(np.genfromtxt(io.BytesIO(data.encode()), delimiter=",", dtype="|S3", autostrip=True))
"""
[[b'1' b'abc' b'2']
 [b'3' b'xxx' b'4']]
"""

print('\n')
print(np.genfromtxt(io.BytesIO(data.encode()), delimiter=",", autostrip=True))
"""
[[  1.  nan   2.]
 [  3.  nan   4.]]
"""

एक तरफ:

dtype = "| Sx", जहां x = किसी भी {1, 2, 3, ...}

dtypes। पायथन में S1 और S2 के बीच अंतर

"| S1 और S2 तार डेटा प्रकार के डिस्क्रिप्टर हैं; पहले का मतलब है कि लंबाई 1 का स्ट्रिंग रखती है, लंबाई का दूसरा 2. ..."



17

रोमन शापोवालोव का कोड Python 3.x के साथ-साथ Python 2.6 / 2.7 में काम करना चाहिए। यहाँ यह फिर से पूरे उदाहरण के साथ है:

import io
import numpy
x = "1 3\n 4.5 8"
numpy.genfromtxt(io.BytesIO(x.encode()))

आउटपुट:

array([[ 1. ,  3. ],
       [ 4.5,  8. ]])

अजगर 3.x के लिए स्पष्टीकरण:

  • numpy.genfromtxt एक बाइट स्ट्रीम (यूनिकोड के बजाय बाइट्स के रूप में व्याख्या की गई फ़ाइल जैसी वस्तु) लेता है।
  • io.BytesIOएक बाइट स्ट्रिंग लेता है और एक बाइट स्ट्रीम देता है। io.StringIOदूसरी ओर, एक यूनिकोड स्ट्रिंग लेगा और एक यूनिकोड स्ट्रीम लौटाएगा।
  • x एक स्ट्रिंग शाब्दिक सौंपा गया है, जो पायथन 3.x में एक यूनिकोड स्ट्रिंग है।
  • encode()यूनिकोड स्ट्रिंग लेता है xऔर इससे एक बाइट स्ट्रिंग बनाता है, इस प्रकार io.BytesIOएक वैध तर्क देता है।

पायथन 2.6 / 2.7 के लिए एकमात्र अंतर यह है कि xएक बाइट स्ट्रिंग (मान लिया from __future__ import unicode_literalsजाता है) का उपयोग नहीं किया जाता है, और फिर encode()बाइट स्ट्रिंग लेता है और फिर xभी उसी बाइट स्ट्रिंग को बाहर करता है। तो परिणाम वही है।


चूंकि यह एसओ के सबसे लोकप्रिय सवालों में से एक है StringIO, यहाँ आयात विवरण और विभिन्न पायथन संस्करणों पर कुछ और स्पष्टीकरण दिया गया है।

यहां वे वर्ग हैं जो एक स्ट्रिंग लेते हैं और एक धारा लौटाते हैं:

  • io.BytesIO(पायथन 2.6, 2.7 और 3.x) - एक बाइट स्ट्रिंग लेता है। एक बाइट स्ट्रीम देता है।
  • io.StringIO(पायथन 2.6, 2.7 और 3.x) - एक यूनिकोड स्ट्रिंग लेता है। एक यूनिकोड स्ट्रीम देता है।
  • StringIO.StringIO(पायथन 2.x) - एक बाइट स्ट्रिंग या यूनिकोड स्ट्रिंग लेता है। यदि बाइट स्ट्रिंग, एक बाइट स्ट्रीम देता है। यदि यूनिकोड स्ट्रिंग, एक यूनिकोड स्ट्रीम लौटाता है।
  • cStringIO.StringIO(पायथन 2.x) - का तेज़ संस्करण StringIO.StringIO, लेकिन यूनिकोड के तार नहीं ले सकते जिनमें गैर-एएससीआईआई अक्षर होते हैं।

ध्यान दें कि के StringIO.StringIOरूप में आयातित है from StringIO import StringIO, तो के रूप में इस्तेमाल किया StringIO(...)। या तो वह, या आप करते हैं import StringIOऔर फिर उपयोग करते हैं StringIO.StringIO(...)। मॉड्यूल नाम और वर्ग का नाम बस एक ही होना है। यह datetimeउस तरह से है।

अपने समर्थित पायथन संस्करणों के आधार पर क्या उपयोग करें:

  • आप केवल अजगर 3.x का समर्थन करते हैं: बस उपयोग io.BytesIOया io.StringIOआधार तरह डेटा के साथ आप काम कर रहे हैं पर।

  • यदि आप Python 2.6 / 2.7 और 3.x दोनों का समर्थन करते हैं, या अपने कोड को 2.6 / 2.7 से 3.x में बदलने की कोशिश कर रहे हैं: सबसे आसान विकल्प अभी भी उपयोग करना है io.BytesIOया io.StringIO। यद्यपि StringIO.StringIOयह लचीला है और इस प्रकार 2.6 / 2.7 के लिए पसंद किया जाता है, यह लचीलापन 3. बग को प्रकट कर सकता है। उदाहरण के लिए, मेरे पास कुछ कोड थे जो कि पायथन संस्करण के आधार पर उपयोग किए गए StringIO.StringIOया io.StringIOनिर्भर थे, लेकिन मैं वास्तव में एक बाइट स्ट्रिंग से गुजर रहा था, इसलिए जब मैंने इसे पायथन 3.x में परीक्षण करने के लिए चारों ओर पाया तो यह विफल हो गया और इसे ठीक करना पड़ा।

    उपयोग करने io.StringIOका एक और लाभ सार्वभौमिक नईलाइन्स के लिए समर्थन है। यदि आप कीवर्ड तर्क पास newline=''करते हैं io.StringIO, तो यह किसी भी , या \n, पर लाइनों को विभाजित करने में सक्षम होगा । मैंने पाया कि विशेष रूप से यात्रा करेंगे ।\r\n\rStringIO.StringIO\r

    ध्यान दें कि यदि आप आयात करते हैं BytesIOया उससे करते StringIOहैं six, तो आप StringIO.StringIOपायथॉन में मिलते हैं 2. x और उपयुक्त वर्ग से ioपायथन 3.x में। यदि आप मेरे पिछले पैराग्राफ के आकलन से सहमत हैं, तो यह वास्तव में एक मामला है जहां आपको बचना चाहिए sixऔर ioइसके बजाय सिर्फ आयात करना चाहिए ।

  • यदि आप पायथन 2.5 या उससे कम और 3.x का समर्थन करते हैं: आपको StringIO.StringIO2.5 या उससे कम की आवश्यकता होगी , तो आप भी इसका उपयोग कर सकते हैं six। लेकिन एहसास है कि यह आम तौर पर 2.5 और 3.x दोनों का समर्थन करना बहुत मुश्किल है, इसलिए आपको अपने सबसे कम समर्थित संस्करण को 2.6 करने पर विचार करना चाहिए यदि संभव हो तो।


7

पायथन 3.5.2 के साथ यहां काम करने के लिए उदाहरण बनाने के लिए , आप निम्नानुसार फिर से लिख सकते हैं:

import io
data =io.BytesIO(b"1, 2, 3\n4, 5, 6") 
import numpy
numpy.genfromtxt(data, delimiter=",")

परिवर्तन का कारण यह हो सकता है कि किसी फ़ाइल की सामग्री डेटा (बाइट्स) में है जो किसी भी तरह से डिकोड होने तक टेक्स्ट नहीं बनाते हैं। genfrombytesसे बेहतर नाम हो सकता है genfromtxt


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.