2012-12-13 40 views
12
>>> 'string with no string formatting markers' % ['string'] 
'string with no string formatting markers' 
>>> 'string with no string formatting markers' % ('string',) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: not all arguments converted during string formatting 

मैं उम्मीद करता हूं कि दोनों मामले TypeError उठाएंगे, लेकिन ऐसा नहीं है। क्यों नहीं?कोई स्ट्रिंग स्वरूपण पैरामीटर के रूप में किसी सूची का उपयोग क्यों नहीं करता है, यहां तक ​​कि% s पहचानकर्ता के साथ, मूल स्ट्रिंग को वापस नहीं करता है?

Python documentation इस विषय पर स्ट्रिंग्स, टुपल्स और डिक्शनरी के बारे में बात करते हैं, लेकिन सूचियों के बारे में कुछ नहीं कहते हैं। मैं इस व्यवहार के बारे में थोड़ा उलझन में हूँ। मैं इसे पायथन 2.7 और 3.2 में डुप्लिकेट करने में सक्षम हूं।

+1

मेरे लिए एक गैर-दस्तावेजी "सुविधा" (बग) की तरह लग रहा। – mgilson

+0

Fwiw, 'jython2.2.1' * * बढ़ा है एक' – mgilson

उत्तर

6

ध्यान से पढ़ना, प्रलेखन कहा गया है कि:

प्रारूप एक भी तर्क की आवश्यकता है, मानों एक भी गैर tuple वस्तु हो सकता है। अन्यथा, मान स्ट्रिंग द्वारा निर्दिष्ट वस्तुओं की संख्या या एक मैपिंग ऑब्जेक्ट (उदाहरण के लिए, एक शब्दकोश) के साथ tuple होना चाहिए।

अब, इस मामले में format एक भी तर्क की आवश्यकता नहीं है और इस तरह के दस्तावेज़ हमें बताता है कि आप एक tuple या तर्क के रूप में एक मानचित्रण का उपयोग करना चाहिए; अन्य मामले "अपरिभाषित व्यवहार" में पड़ते हैं (जो हो रहा है: व्यवहार सभी मामलों में संगत नहीं है)।

इसे शायद प्रश्न का अंतिम उत्तर माना जाना चाहिए: यदि list (या tuple या मैपिंग से अलग किसी भी प्रकार) का उपयोग करके स्ट्रिंग में कोई प्रारूप विनिर्देश नहीं है, तो इसे केवल एक बग माना जाना चाहिए अपरिभाषित व्यवहार।

इस से इस प्रकार है कि आप हमेशा एक tuple या dict तर्क के रूप में उपयोग करने के लिए चाहिए, अन्यथा आप हाथ से प्रारूप विनिर्देशक के लिए जाँच या विषम व्यवहार को संभालने के लिए है।

अपने मामले में आप के बजाय (['string'],) का उपयोग कर समस्या को ठीक कर सकते हैं।


संभव क्यों परिणामी व्यवहार इतना यादृच्छिक प्रतीत हो रहा है की "विवरण":

ऐसा लगता है कि वहाँ के बजाय this लाइन पर PyMappingCheck का उपयोग करने का PyString_Format/PyUnicode_Format के मूल कार्यान्वयन में एक गाड़ी check था, :

:

if (PyMapping_Check(args) && !PyTuple_Check(args) && 
    !PyObject_TypeCheck(args, &PyBaseString_Type)) 
    dict = args; 

यह इस कोड इस्तेमाल किया गया था

जो बराबर नहीं है। उदाहरण के लिए set में tp_as_mapping सेट नहीं है (कम से कम Python2.7.3 स्रोत कोड जो मैंने कुछ हफ्ते पहले डाउनलोड किया है), जबकि list इसे सेट करता है।

यही वजह है कि list (और संभवतः अन्य वस्तुओं) TypeError जबकि, set, int और कई अन्य कर नहीं उठता हो सकता है।

जैसा कि मैंने इस एक ही जवाब में पहले कहा TypeError मिल मैं भी list रों साथ:

$ python2 
Python 2.7.3 (default, Sep 26 2012, 21:53:58) 
[GCC 4.7.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> 'some string' % [] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: not all arguments converted during string formatting 

यह शायद पता चलता है कि इसके बाद के संस्करण मुद्दा केवल एक ही यहाँ नहीं है।

मैं मानता हूँ कि, सिद्धांत में , तर्क की संख्या अगर तर्क एक टपल नहीं है चेक नहीं किया गया स्रोत कोड को देखते हुए, लेकिन इस 'some string' % 5 -> 'some string' और नहीं एक TypeError, अर्थ होगा तो वहाँ कुछ में गड़बड़ होना चाहिए वह कोड

+2

TypeError' अजगर 2 की कौन-सा संस्करण कोशिश कर रहे हैं? मैं इसे 2.5.4, 2.6.1 या 2.7.2 – geoffspear

+0

पर पुन: उत्पन्न नहीं कर सकता, यह दिलचस्प है, यह आपके लिए पायथन 2 में 'TypeError' उठाता है? यह मेरे लिए नहीं है: 'पायथन 2.7.3 (डिफ़ॉल्ट, 1 अगस्त 2012, 05:14:39) [जीसीसी 4.6.3] linux2 पर" सहायता "," कॉपीराइट "," क्रेडिट "टाइप करें या अधिक जानकारी के लिए "लाइसेंस"। >>> 'कुछ स्ट्रिंग'% ['ए'] 'कुछ स्ट्रिंग' –

+1

मुझे आपके द्वारा दिखाए जा रहे 'टाइपरर'' नहीं मिलते हैं (और सवाल से, मुझे नहीं लगता कि ओपी भी है) यानी '" foobar "% ['बतख'] 'खुशी से लौटता है'" foobar "'। मैं ओएस-एक्स 10.5.8 पर पायथन 2.7.3, 2.6.4, 3.2.3 का उपयोग कर रहा हूं ... उबंटू पर पायथन 2.7.3, 2.6.5, 3.2.0 के साथ कोई त्रुटि नहीं – mgilson