2010-08-04 9 views
9

मैं वास्तव में अपने पाइथन एप्लिकेशन सौदे को आंतरिक रूप से यूनिकोड तारों के साथ विशेष रूप से रखना चाहता हूं। यह हाल ही में मेरे लिए अच्छा रहा है, लेकिन मैंने पथों को संभालने के साथ एक समस्या में भाग लिया है। फाइल सिस्टम के लिए POSIX API यूनिकोड नहीं है, इसलिए फाइलों के लिए "अनावश्यक" नाम होने के लिए यह संभव है (और वास्तव में कुछ हद तक आम है): फ़ाइल नाम जो फाइल सिस्टम के निर्दिष्ट एन्कोडिंग में एन्कोड नहीं किए गए हैं।पायथन में अनावश्यक फ़ाइल नामों को कैसे संभालें?

पायथन में, यह unicode और str के मिश्रण के रूप में प्रकट होता है os.listdir() से वस्तुओं को वापस किया जा रहा है।

>>> os.listdir(u'/path/to/foo') 
[u'bar', 'b\xe1z'] 

कि उदाहरण में, चरित्र '\xe1' लैटिन -1 में एन्कोड या somesuch, तब भी जब (काल्पनिक) फाइल सिस्टम की रिपोर्ट sys.getfilesystemencoding() == 'UTF-8' (UTF-8 में, उस चरित्र '\xc3\xa1' दो बाइट्स होगा) है। इस कारण से, यदि आप उपयोग करने का प्रयास करते हैं, तो उदाहरण के लिए, os.path.join() यूनिकोड पथ के साथ, आपको फ़ाइल नाम 0 डीमिल जाएगा, क्योंकि फ़ाइल नाम को डीकोड नहीं किया जा सकता है।

नोट है कि ज्यादातर मौकों में, यूनिकोड एपीआई इस्तेमाल किया जाना चाहिए:

Python Unicode HOWTO यूनिकोड pathnames के बारे में यह सलाह प्रदान करता है। बाइट्स एपीआई केवल उन सिस्टमों पर उपयोग की जानी चाहिए जहां अनावश्यक फ़ाइल नाम मौजूद हो सकते हैं, यानी यूनिक्स सिस्टम।

क्योंकि मैं मुख्य रूप से यूनिक्स सिस्टम की परवाह करता हूं, इसका मतलब यह है कि मुझे केवल अपने कार्यक्रम को पथ के लिए बाइटिंग के साथ सौदा करने के लिए पुनर्गठन करना चाहिए? (यदि हां, तो मैं विंडोज संगतता को कैसे बनाए रख सकता हूं?) या अवांछित फ़ाइल नामों से निपटने के बेहतर तरीके हैं? क्या वे "जंगली में" दुर्लभ हैं कि मुझे सिर्फ उपयोगकर्ताओं को उनकी लानत फाइलों का नाम बदलने के लिए कहा जाना चाहिए?

(यदि यह सबसे अच्छा है बस आंतरिक bytestrings से निपटने के लिए, मैं एक अनुवर्ती सवाल है: मैं कैसे एक स्तंभ के लिए SQLite में bytestrings की दुकान है, जबकि के रूप में अनुकूल यूनिकोड तार डेटा के बाकी रखने करते हैं)

उत्तर

4

यदि आप पाइथन 3 पर स्विच करने के इच्छुक हैं, तो पाइथन को समस्या का समाधान होता है।1 या बाद में:

PEP 383 - Non-decodable Bytes in System Character Interfaces। पहले पैराग्राफ के लिए

+0

धन्यवाद! मुझे इस पीईपी के बारे में पता नहीं था। यह एक बहुत चालाक समाधान है। – adrian

2

हैं आपको यूनिकोड के लिए तैयार डीबी में बाइटस्टर्स स्टोर करने की आवश्यकता है, तो हेक्स में एन्कोडेड बाइटस्टर्स रिकॉर्ड करना संभवतः संभव है। इस तरह, हेक्स-एन्कोडेड स्ट्रिंग डीबी में यूनिकोड स्ट्रिंग के रूप में स्टोर करने के लिए सुरक्षित है।

यूनिक्स पथनाम मुद्दे के लिए, मेरी समझ यह है कि फ़ाइल नामों के लिए लागू कोई विशेष एन्कोडिंग नहीं है, इसलिए विभिन्न फाइलों पर लैटिन -1, केओआई -8-आर, सीपी 1252 और अन्य होना पूरी तरह से संभव है। इसका मतलब है कि पथनाम में प्रत्येक घटक में एक अलग एन्कोडिंग हो सकती है।

मैं chardet module जैसे कुछ का उपयोग कर फ़ाइल नामों के एन्कोडिंग को आजमाने और अनुमान लगाने का लुत्फ उठाउंगा। बेशक, कोई गारंटी नहीं है इसलिए आपको अभी भी अपवादों को संभालना होगा, लेकिन आपके पास कम अपरिवर्तनीय नाम होंगे। कुछ सॉफ़्टवेयर अपरिवर्तनीय वर्णों को प्रतिस्थापित करते हैं? जो गैर-परिवर्तनीय है। मैं उन्हें \ xdd या \ xdddd के साथ प्रतिस्थापित कर दूंगा क्योंकि यदि आवश्यक हो तो इसे मैन्युअल रूप से उलट दिया जा सकता है। कुछ अनुप्रयोगों में स्ट्रिंग को किसी उपयोगकर्ता को प्रस्तुत करना संभव हो सकता है ताकि वे अनकोड करने योग्य लोगों को प्रतिस्थापित करने के लिए यूनिकोड वर्णों में कुंजी कर सकें।

यदि आप इस मार्ग पर जाते हैं, तो आप इस नौकरी को संभालने के लिए विस्तारित चार्ट समाप्त कर सकते हैं। यह एक उपयोगिता के साथ पूरक करना अच्छा होगा जो फाइल सिस्टम को अपरिवर्तनीय नाम ढूंढने के लिए स्कैन करता है और एक सूची तैयार करता है जिसे संपादित किया जा सकता है, फिर वापस खिलाया जाता है, यूनिकोड समकक्षों के साथ सभी नामों को ठीक करने के लिए।

+0

+1 - अनावश्यक डेटा से निपटने का सबसे अच्छा तरीका यह है कि यदि संभव हो तो इसे डीकोड करने से बचें। सूची को स्कैन करें और फाइल सिस्टम एन्कोडिंग का उपयोग करके एक बाइट स्ट्रिंग पर यूनिकोड ऑब्जेक्ट को वापस एन्कोड करें। मौजूदा अपरिवर्तनीय बाइट तारों को छूटे रहना चाहिए। – detly

+0

हां; सलाह के लिए धन्यवाद। मैंने डुबकी ली है और बाइट स्ट्रिंग पथ पर पूरी तरह से स्विच किया है (कम से कम पायथन 2.x के लिए)। रिकॉर्ड के लिए, SQLite में उन्हें संग्रहीत करने से पहले बफर ऑब्जेक्ट्स में स्ट्र ऑब्जेक्ट्स को लपेटना उन्हें यूटीएफ -8 के रूप में स्वचालित रूप से डीकोड करने से रोकता है। – adrian

संबंधित मुद्दे