अजगर में int () का काउंटरिंटुइक्टिव व्यवहार


83

डॉक्स में यह स्पष्ट रूप से कहा गया है कि int (संख्या) एक फ़्लोरिंग प्रकार रूपांतरण है:

int(1.23)
1

और int (string) एक int देता है यदि और केवल अगर स्ट्रिंग एक पूर्णांक शाब्दिक है।

int('1.23')
ValueError

int('1')
1

क्या इसकी कोई खास वजह है? मुझे यह स्पष्ट प्रतीत होता है कि एक मामले में फ़ंक्शन फर्श है, लेकिन दूसरा नहीं।

जवाबों:


123

कोई विशेष कारण नहीं है। पायथन बस निहित रूपांतरणों को न करने के अपने सामान्य सिद्धांत को लागू कर रहा है, जो कि विशेष रूप से नए लोगों के लिए, पर्ल और जावास्क्रिप्ट जैसी भाषाओं में समस्याओं के प्रसिद्ध कारण हैं।

int(some_string)एक स्ट्रिंग को पूर्णांक प्रारूप में बदलने का एक स्पष्ट अनुरोध है; इस रूपांतरण के नियम निर्दिष्ट करते हैं कि स्ट्रिंग में एक मान्य पूर्णांक शाब्दिक प्रतिनिधित्व होना चाहिए। int(float)एक फ्लोट को पूर्णांक में बदलने के लिए एक स्पष्ट अनुरोध है; इस रूपांतरण के नियम निर्दिष्ट करते हैं कि फ्लोट का आंशिक भाग छोटा हो जाएगा।

के लिए आदेश में int("3.1459")वापस जाने के लिए 3दुभाषिया परोक्ष एक नाव के लिए स्ट्रिंग में कनवर्ट करने के लिए होगा। चूंकि पायथन निहित रूपांतरणों का समर्थन नहीं करता है, इसलिए वह इसके बजाय अपवाद को चुनना चाहता है।


type(3)लौटता है <type int>। हालांकि, अजगर शिकायत नहीं करता है float("3")। क्या अजगर अंतर्निहित रूप से स्ट्रिंग को इंट में परिवर्तित नहीं कर रहा है और फिर फ्लोट में?
— फ़्रैंकेंड्स

नंबर "3" एक मान्य फ्लोटिंग-पॉइंट वैल्यू है, भले ही एक प्रोग्राम शाब्दिक के रूप में इसे एक पूर्णांक के रूप में व्याख्या किया जाएगा। कोई पूर्णांक रूपांतरण आवश्यक नहीं है।
— होल्डनवेब

75

यह लगभग निश्चित रूप से पायथन के ज़ेन से तीन सिद्धांतों को लागू करने का मामला है :

स्पष्ट रूप से बेहतर निहित है।

[...] व्यावहारिकता शुद्धता को हरा देती है

त्रुटियों को कभी भी चुपचाप नहीं गुजरना चाहिए

कुछ प्रतिशत समय, कोई ऐसा कर रहा int('1.23')है जो अपने उपयोग के मामले के लिए गलत रूपांतरण को बुला रहा है, और कुछ ऐसा चाहता है floatया decimal.Decimalइसके बजाय। इन मामलों में, उनके लिए यह स्पष्ट रूप से बेहतर है कि वे एक गलत त्रुटि प्राप्त कर सकते हैं जो वे चुपचाप कर सकते हैं, बजाय चुपचाप गलत मूल्य देने के।

ऐसा होता है कि आप में है काटना चाहते हैं कि किसी पूर्णांक पर, यह मामूली बात है स्पष्ट रूप से इसे माध्यम से गुजर द्वारा ऐसा करने के लिए floatपहले, और फिर से एक फोन कर int, round, trunc, floorया ceilके रूप में उपयुक्त। यह आपके कोड को अधिक स्व-दस्तावेज़ीकरण भी बनाता है, बाद के संशोधन के खिलाफ एक काल्पनिक "सुधार" को बनाए रखने के लिए एक काल्पनिक चुपचाप-चकरा देने वाली intकॉल floatकरके यह स्पष्ट करता है कि गोल मूल्य वह है जो आप चाहते हैं।


मुझे लगता है कि ज़ेन तैयार होने से बहुत पहले उन सिद्धांतों को अपनाया गया था, लेकिन दोनों में से किसी भी तरह से सामंजस्य दिखाई देगा।
— होल्डनवेब

17

कभी-कभी एक सोचा प्रयोग उपयोगी हो सकता है।

  • व्यवहार A: int('1.23')एक त्रुटि के साथ विफल रहता है। यह मौजूदा व्यवहार है।
  • व्यवहार बी: त्रुटि के बिना int('1.23')पैदा करता है 1। यह वही है जो आप प्रस्तावित कर रहे हैं।

व्यवहार A के साथ, यह व्यवहार B के प्रभाव को प्राप्त करने के लिए सीधा और तुच्छ है: int(float('1.23'))इसके बजाय का उपयोग करें ।

दूसरी ओर, व्यवहार बी के साथ, व्यवहार ए का प्रभाव प्राप्त करना काफी अधिक जटिल है:

def parse_pure_int(s):
    if "." in s:
        raise ValueError("invalid literal for integer with base 10: " + s)
    return int(s)

(और यहां तक ​​कि ऊपर दिए गए कोड के साथ, मुझे पूरा भरोसा नहीं है कि कुछ कोने का मामला नहीं है कि यह गलतफहमी है।)

व्यवहार A इसलिए व्यवहार B से अधिक अभिव्यंजक है।

एक और बात पर विचार करें: '1.23'एक फ्लोटिंग-पॉइंट वैल्यू का एक स्ट्रिंग प्रतिनिधित्व है। परिवर्तित '1.23'एक पूर्णांक के लिए धारणात्मक दो रूपांतरण (पूर्णांक के लिए नाव के लिए स्ट्रिंग) शामिल है, लेकिन int(1.23)और int('1')प्रत्येक केवल एक रूपांतरण शामिल है।


संपादित करें:

और वास्तव में, कोने के मामले हैं जो उपरोक्त कोड नहीं संभालेंगे: 1e-2और 1E-2दोनों अस्थायी बिंदु मान भी हैं।


स्पष्ट करने के लिए: मैं व्यवहार बी का प्रस्ताव नहीं करूंगा, क्योंकि यह सिर्फ उतना ही खतरनाक है, जितना कि आप और अन्य ने कहा है। मुझे यकीन नहीं है कि मौजूदा एक से भी बेहतर समाधान मौजूद है। एक विकल्प यह होगा कि फ़ंक्शन को अलग-अलग नाम दिए जाएं, लेकिन यह केवल टाइप करने के लिए अधिक सामान है। Int (1.23) विफल होने का स्पष्ट समाधान और केवल पूर्णांक (साथ-साथ-दशमलव-स्थानों) पूर्णांक को वापस करने से गतिशील रूप से टाइप की गई भाषा में कोई मतलब नहीं है।
— स्टीफन एस

1
कॉर्नर भी मामला हो सकता है int('123E-2')या int('1L')।
— जारेड गोगुएन

11

सरल शब्दों में - वे समान कार्य नहीं हैं।

  • int (दशमलव) 'मंजिल के रूप में व्यवहार करता है यानी दशमलव भाग को खटखटाता है और int के रूप में लौटता है'
  • int (string) यह व्यवहार करता है कि 'यह पाठ एक पूर्णांक का वर्णन करता है, इसे रूपांतरित करें और int के रूप में लौटें'।

वे एक ही नाम के साथ 2 अलग-अलग कार्य हैं जो पूर्णांक लौटाते हैं लेकिन वे अलग-अलग कार्य हैं।

'int' छोटा और याद रखने में आसान है और इसका अर्थ प्रत्येक प्रकार पर लागू होता है, अधिकांश प्रोग्रामर के लिए सहज होता है, यही वजह है कि उन्होंने इसे चुना।

इसका कोई निहितार्थ नहीं है कि वे समान या संयुक्त कार्यक्षमता प्रदान कर रहे हैं, उनके पास बस एक ही नाम है और एक ही प्रकार वापस करते हैं। उन्हें आसानी से 'फ्लोरडेसिमलएएसआईएनटी' और 'कन्वर्टस्ट्रीमिंगटॉइंट' कहा जा सकता है, लेकिन वे 'इंट' के लिए गए क्योंकि यह याद रखना आसान है, (99%) सहज और भ्रम शायद ही कभी होगा।

पाठ के लिए एक पूर्णांक के रूप में पार्सिंग पाठ जिसमें दशमलव बिंदु शामिल था जैसे कि "4.5" कंप्यूटर भाषाओं के बहुमत में एक त्रुटि फेंक देगा और अधिकांश प्रोग्रामर द्वारा एक त्रुटि फेंकने की उम्मीद की जाएगी , क्योंकि पाठ-मान एक पूर्णांक और तात्पर्य का प्रतिनिधित्व नहीं करता है वे गलत डेटा प्रदान कर रहे हैं


2
फिर दो 'अलग-अलग कार्यों' का एक ही नाम क्यों है? कुछ ज़ेन बकवास के उल्लंघन की तरह लगता है।
— हॉब्स

क्योंकि नाम 2 अलग-अलग कार्यों के लिए समझ में आता है और संक्षिप्त है। Int-ify एक दशमलव (मंजिल), एक स्ट्रिंग को एक इंट (रूपांतरण) में परिवर्तित करें

तकनीकी रूप से यह याद रखने में मदद मिल सकती है कि intयह एक प्रकार है (और उस पर एक निर्मित)। इसके निर्माता ( __new__) कई संभावित तर्क प्रकारों को लेते हैं। प्रत्येक प्रकार के लिए इसका व्यवहार अच्छी तरह से परिभाषित है।
— होल्डनवेब

यह उत्तर केवल गलत है जैसा कि कहा गया है। intवास्तव में एक फ़ंक्शन नहीं है, लेकिन एक प्रकार है, जिसके तरीके __new__और __init__तरीके एक स्ट्रिंग या फ्लोट तर्क लेते हैं, प्रत्येक उचित रूप से व्यवहार करते हैं। यह कहना अधिक सटीक होगा कि प्रकार दो तर्क प्रकारों को अलग-अलग तरीके से संसाधित करता है, लेकिन केवल एक ही है int।
— होल्डनवेब
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.