2010-04-07 13 views
9

मैं यूनिकोड फ़ाइल नाम के साथ subprocess.call() को चलाने के लिए कोशिश कर रहा हूँ, और यहाँ के लिए फ़ाइल नाम सरल है समस्या:यूनिकोड अजगर subprocess.call()

n = u'c:\\windows\\notepad.exe ' 
f = u'c:\\temp\\nèw.txt' 

subprocess.call(n + f) 

जो प्रसिद्ध त्रुटि को जन्म देती है:

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe8'

utf-8 के लिए एन्कोडिंग गलत फ़ाइल नाम पैदा करता है, और MBCS लहजे

बिना new.txt के रूप में फ़ाइल नाम से गुजरता है मैं तो बस किसी भी अधिक इस भ्रामक विषय और सर्कल में स्पिन पर नहीं पढ़ सकता। तो मैं में शामिल होने और अपने आप को

धन्यवाद

+0

आपके ऑपरेटिंग सिस्टम के आधार पर, यदि आप अपने एन्कोडिंग के रूप में लैटिन -1 या सीपी 1252 का उपयोग करते हैं तो क्या होता है? –

+1

क्या आपने स्रोत फ़ाइल का एन्कोडिंग निर्दिष्ट किया है? –

+0

स्रोत फ़ाइल utf एन्कोडेड है: # - * - कोडिंग: utf-8 - * - मैं समय-समय पर लैटिन -1 के साथ चाल का उपयोग करता हूं लेकिन इस मामले में नहीं: 1. मुझे अन्य पात्रों की भी आवश्यकता है लैटिन -1 में नहीं हैं 2. दुर्भाग्यवश यह सबप्रोसेस के साथ काम नहीं करता है - एक ही त्रुटि उठाई जाती है, मैंने एक ही लैटिन -1 एन्कोडिंग दोनों स्ट्रिंग्स को एन्कोड किया है सभी उत्तरों के लिए धन्यवाद – otrov

उत्तर

0

मैं तुम्हारे लिए एक जवाब नहीं है मदद के लिए पूछना सोचा था कि मैं यहां पूर्व में कई अलग अलग समस्याओं के लिए जवाब में से बहुत कुछ पाया है, लेकिन मैं भी पर्याप्त मात्रा में किया है इस समस्या में अनुसंधान करें। पाइथन सभी आउटपुट (सिस्टम कॉल सहित) को उसी वर्ण में परिवर्तित करता है जैसे टर्मिनल में चल रहा है। विंडोज टर्मिनल कैरेक्टर मैपिंग के लिए कोड पेज का उपयोग करते हैं; डिफ़ॉल्ट कोड पृष्ठ 437 है, लेकिन इसे chcp कमांड के साथ बदला जा सकता है। chcp 65001 सैद्धांतिक रूप से कोड पृष्ठ को utf-8 में बदल देगा, लेकिन जहां तक ​​मुझे पता है कि पाइथन को पता नहीं है कि इसके साथ क्या करना है, तो आप एसओएल हैं।

1

ऐसा प्रतीत होता है कि इस काम को करने के लिए, उपप्रोसेस कोड को CreateProcess के विस्तृत वर्ण संस्करण का उपयोग करने के लिए संशोधित किया जाना चाहिए (यह मानते हुए कि कोई मौजूद है)। http://www.python.org/dev/peps/pep-0277/ पर फ़ाइल ऑब्जेक्ट के लिए किए गए एक ही बदलाव पर चर्चा करने वाला एक पीईपी है, शायद आप विंडोज सी कॉल का शोध कर सकते हैं और सबप्रोसेस के लिए एक समान परिवर्तन का प्रस्ताव दे सकते हैं।

+0

I के साथ यूनिकोड तर्कों का समर्थन करना चाहिए। इस समस्या में शोध करने के लिए कार्य को महसूस न करें, आप इसके लेखक (नील) को देखकर मजाकिया हैं, जिन्होंने यूनिकोड (चौड़े चार) फ़ाइल नाम का उपयोग – otrov

0

आप के रूप में फ़ाइल को खोलने की कोशिश कर सकते हैं:

subprocess.call((n + f).encode("cp437")) 

या जो भी कोड पृष्ठ पर एक कमांड प्रॉम्प्ट विंडो में इस्तेमाल किया जा रहा के रूप में chcp रिपोर्ट। यदि आप स्टारबक सुझाव के रूप में chcp 65001 पर आज़माते हैं, तो आपको stdlib एन्कोडिंग \ aliases.py फ़ाइल को संपादित करना होगा और cp65001 को पहले से 'utf-8' के उपनाम के रूप में जोड़ना होगा। यह पायथन स्रोत में एक खुला मुद्दा है।

अद्यतन: चूंकि यह एक कमांड परिदृश्य है, इस तरह के कमांड चलाने से पहले, सुनिश्चित करें कि आप पहले chcp कमांड चलाएं, आउटपुट का विश्लेषण करें और वर्तमान "कमांड प्रॉम्प्ट" (डॉस) कोडपेज पुनर्प्राप्त करें। इसके बाद, subprocess.call तर्क को एन्कोड करने के लिए खोजे गए कोडपृष्ठ का उपयोग करें।

+0

के समर्थन के साथ विज्ञान 2 2.10 जारी किया है, लेकिन मैं cp1251 पर हूं, लेकिन कार्यक्रम है मनमाने ढंग से लोकेल – otrov

+0

सीपी 1251 के साथ विभिन्न मशीनों पर चलना चाहिए विंडोज कोडपेज है। सबप्रोसेस के साथ कमांड चलाते समय, आपको "डॉस"/कमांड प्रॉम्प्ट कोडपेज का उपयोग करने की आवश्यकता होती है। – tzot

+0

@tzot: यह गलत है जब तक कि आप 'एमबीसीएस' एन्कोडिंग का मतलब नहीं रखते (आप 'locale.getpreferredencoding() 'का उपयोग करके अपना मान देख सकते हैं) और ओपी पहले ही कह चुका है कि उसके सिस्टम पर' mbcs' आवश्यक वर्णों का समर्थन नहीं करता है।'chcp' अलग-अलग एन्कोडिंग वापस कर सकता है। – jfs

0

जैसा कि ΤΖΩΤΖΙΟΥ और स्टारबक का उल्लेख किया गया है, समस्या कंसोल कोड पेज के साथ है जो आपके मामले में 866 (विंडोज़ के रूसीकरण में) है और 1251 नहीं है। बस कंसोल में chcp चलाएं।

समस्या तब होती है जब आप विंडोज कंसोल पर आउटपुट यूनिकोड चाहते हैं। दुर्भाग्यवश आपको कम से कम रिकॉन्स्टर और उपनाम के लिए एन्कोडिंग के लिए 'cp866' के रूप में एन्कोडिंग \ aliases.py (या इसे स्क्रिप्ट स्टार्ट पर प्रोग्रामेटिक रूप से करें) की आवश्यकता होगी और नोटपैड चलाने से पहले कंसोल के कोड पेज को 65001 में बदल दें और इसे बाद में सेट करें ।

chcp 65001 & c:\WINDOWS\notepad.exe nèw.txt & chcp 866 

वैसे, कंसोल में आदेश चला और फ़ाइल नाम सही ढंग से देखने के लिए सक्षम होने के लिए आपको कंसोल विंडो के गुणों में ल्युसिडा कंसोल को सांत्वना फ़ॉन्ट बदलने की जरूरत होगी।

यह और भी बदतर हो सकता है: आपको वर्तमान प्रक्रिया के कोड पेज को बदलने की आवश्यकता होगी। ऐसा करने के लिए, आपको स्क्रिप्ट शुरू होने से ठीक पहले chcp 65001 चलाने की आवश्यकता होगी या स्क्रिप्ट के भीतर इसे करने के लिए pywin32 का उपयोग करें।

+0

सभी प्रयासों के लिए धन्यवाद, बहुत सराहना की :) दुर्भाग्यवश मैं इसे काम पर नहीं कर सकता। स्ट्रिंग को subprocess(), या अधिक सटीक CreateProcess() को "chcp 65001 और c: \ windows \ notepad.exe nèw.txt" के रूप में मुद्रित किया गया है जो त्रुटि को फेंकता है "सिस्टम निर्दिष्ट फ़ाइल नहीं ढूंढ सकता"। हो सकता है कि मैं इसे गलत तरीके से कर रहा हूं लेकिन मैंने कोशिश की कि मैं क्या समझता हूं मुझे अपने वर्तमान सीपी में विंडोज कंसोल में यूनिकोड फ़ाइल नाम चिपकाने में समस्या नहीं है, जिसे यहां देखा जा सकता है: http://img402.imageshack.us/img402/ 9875/sshot1x.png – otrov

6

यदि आपकी फ़ाइल मौजूद है, तो आप short filename (उर्फ 8.3 नाम) का उपयोग कर सकते हैं। मौजूदा नामों के लिए इस नाम को परिभाषित किया गया है, और तर्क के रूप में पारित होने पर गैर-यूनिकोड जागरूक प्रोग्रामों में कोई परेशानी नहीं होनी चाहिए।

एक तरह से एक प्राप्त करने के लिए (जरूरत Pywin32 स्थापित होने के लिए):

import win32api 
short_path = win32api.GetShortPathName(unicode_path) 

वैकल्पिक रूप से, आप भी ctypes उपयोग कर सकते हैं:

import ctypes 
import ctypes.wintypes 

ctypes.windll.kernel32.GetShortPathNameW.argtypes = [ 
    ctypes.wintypes.LPCWSTR, # lpszLongPath 
    ctypes.wintypes.LPWSTR, # lpszShortPath 
    ctypes.wintypes.DWORD # cchBuffer 
] 
ctypes.windll.kernel32.GetShortPathNameW.restype = ctypes.wintypes.DWORD 

buf = ctypes.create_unicode_buffer(1024) # adjust buffer size, if necessary 
ctypes.windll.kernel32.GetShortPathNameW(unicode_path, buf, len(buf)) 

short_path = buf.value 
+2

हे, यह बिल्कुल घृणित है! हालांकि आसान – jambox

0

उपयोग os.startfile आपरेशन संपादित साथ। यह बेहतर काम करेगा क्योंकि यह आपके एक्सटेंशन के लिए डिफ़ॉल्ट एप्लिकेशन खुल जाएगा।

6

मुझे एक अच्छा कामकाज मिला, यह थोड़ा गन्दा है, लेकिन यह काम करता है।

subprocess.call पाठ को टर्मिनल पर अपने एन्कोडिंग में पास करने जा रहा है, जो कि यह उम्मीद कर रहा है या नहीं। क्योंकि आप इसे पोर्टेबल बनाना चाहते हैं, आपको रनटाइम पर मशीन के एन्कोडिंग को जानना होगा।

निम्नलिखित वर्तमान एन्कोडिंग यह पता लगाने की है और इसलिए

subprocess.call को एक sidenote के रूप सही लागू होता है, मैं भी पाया है

notepad = 'C://Notepad.exe' 
subprocess.call([notepad.encode(sys.getfilesystemencoding())]) 

प्रयास है कि आप एक स्ट्रिंग रचना करने का प्रयास करता है, तो वर्तमान निर्देशिका के साथ,

os.cwd() 

पायथन (या ओएस, पता नहीं) उच्चारण अक्षरों वाले शब्दों को गड़बड़ कर देगा। इसे रोकने के लिए मुझे निम्नलिखित कार्य मिल गए हैं:

os.cwd().decode(sys.getfilesystemencoding()) 

जो ऊपर दिए गए समाधान के समान है।

उम्मीद है कि यह मदद करता है।

+0

ओपी कहता है: * "एमबीसी फाइल के नाम को बिना accent के new.txt के रूप में पास करता है" *। 'mbcs'' sys.getfilesystemencoding() 'विंडोज़ पर है,' .encode (sys.getfilesystemencoding()) 'इस मामले में काम नहीं करता है। – jfs

+0

@ जेएफ। सेबेस्टियन हम एक ही ओपी नहीं देखते हैं;) फ़ाइल 'nèw.txt' उच्चारण के साथ है। – Kpym

+0

@Kpym: यह प्रश्न से सीधा उद्धरण है जिसका अर्थ है कि विंडोज एएनएसआई कोडपेज ('एमबीसीएस') का उपयोग करके एक यूनिकोड नाम को उच्चारण (' nèw.txt') के साथ एन्कोड करना ओपी के सिस्टम पर उच्चारण खो सकता है जैसे कि, यू 'nèw.txt'.encode (' ascii ',' अनदेखा ') '->' b'new.txt'' (वास्तविक कोडपृष्ठ ascii नहीं है) – jfs

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