वास्तव में __future__ आयात से क्या करता है?

| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |

मेरे पास पाइथन में पूर्ण आयात के संबंध में एक प्रश्न का उत्तर है, जो मुझे लगा कि मैं पढ़ने के आधार पर समझ गया हूं पायथन 2.5 चेंजलॉग और साथ में PEP. हालाँकि, Python 2.5 को स्थापित करने और from __future__ importAbsolute_import का ठीक से उपयोग करने का एक उदाहरण तैयार करने का प्रयास करने पर, मुझे एहसास हुआ कि चीजें इतनी स्पष्ट नहीं हैं।

सीधे ऊपर लिंक किए गए चैंज से, यह कथन ने पूर्ण आयात परिवर्तन के बारे में मेरी समझ को सटीक रूप से सारांशित किया:

मान लें कि आपके पास इस तरह की एक पैकेज निर्देशिका है:

pkg/ pkg/__init__.py pkg/main.py pkg/string.py 

यह pkg नामक पैकेज को परिभाषित करता है जिसमें pkg.main और शामिल हैं। pkg.string सबमॉड्यूल।

main.py मॉड्यूल में कोड पर विचार करें। यदि यह कथन आयात स्ट्रिंग को निष्पादित करता है तो क्या होगा? Python 2.4 और इससे पहले के संस्करण में, यह सापेक्ष आयात करने के लिए पहले पैकेज की निर्देशिका में देखेगा, pkg/string.py ढूंढता है, उस फ़ाइल की सामग्री को pkg.string मॉड्यूल के रूप में आयात करता है, और वह मॉड्यूल नाम के लिए बाध्य है "string" pkg.main मॉड्यूल के नामों में गति।

इसलिए मैंने यह सटीक निर्देशिका संरचना बनाई:

$ ls -R .: pkg/ ./pkg: __init__.py main.py string .py 

__init__.py और string.py खाली हैं। main.py में निम्न कोड शामिल है:

आयात स्ट्रिंग प्रिंट string.ascii_uppercase 

उम्मीद के मुताबिक, इसे Python 2.5 के साथ चलाना AttributeError के साथ विफल रहता है:

$ python2.5 pkg/main.py Traceback (सबसे हालिया कॉल अंतिम): फ़ाइल "pkg/main.py", पंक्ति 2 , <मॉड्यूल> प्रिंट string.ascii_uppercase AttributeError: "मॉड्यूल" ऑब्जेक्ट में कोई विशेषता नहीं है "ascii_uppercase" 

हालाँकि, आगे 2.5 चैंज में, हम इसे पाते हैं (जोर जोड़ा गया):

पायथन 2.5 में, आप आयात" के व्यवहार को __future__ से __future__ आयात निरपेक्ष_आयात निर्देश का उपयोग करके निरपेक्ष आयात पर स्विच कर सकते हैं। यह निरपेक्ष-आयात व्यवहार डिफ़ॉल्ट हो जाएगा भविष्य का संस्करण (शायद पायथन 2.7)। एक बार पूर्ण आयात डिफ़ॉल्ट हो जाने पर, आयात स्ट्रिंग हमेशा मानक पुस्तकालय का संस्करण ढूंढेगा।

इस प्रकार मैंने pkg/main2.py बनाया, जो main.py के समान है लेकिन अतिरिक्त भावी आयात निर्देश के साथ। यह अब इस तरह दिखता है:

from __future__ आयात निरपेक्ष_आयात आयात स्ट्रिंग प्रिंट string.ascii_uppercase 

इसे Python 2.5 के साथ चलाना, हालांकि... एक के साथ विफल हो जाता है AttributeError:

$ python2.5 pkg/main2.py Traceback (सबसे हालिया कॉल अंतिम): फ़ाइल "pkg/main2.py", पंक्ति 3, < में ;मॉड्यूल> प्रिंट string.ascii_uppercase AttributeError: "मॉड्यूल" ऑब्जेक्ट में कोई विशेषता नहीं है "ascii_uppercase" 

यह बहुत ही स्पष्ट रूप से इस कथन का खंडन करता है कि आयात स्ट्रिंग हमेशा होगा मजबूत> पूर्ण आयात सक्षम के साथ एसटीडी-लिब संस्करण खोजें। इसके अलावा, चेतावनी के बावजूद कि पूर्ण आयात "नया डिफ़ॉल्ट" व्यवहार बनने के लिए निर्धारित है, मैंने __future__ निर्देश के साथ या उसके बिना, Python 2.7 दोनों का उपयोग करके इसी समस्या का सामना किया:

$ python2.7 pkg/main.py ट्रेसबैक (सबसे हालिया कॉल अंतिम): फ़ाइल "pkg/main.py", पंक्ति 2, <मॉड्यूल> प्रिंट string.ascii_uppercase विशेषता त्रुटि: "मॉड्यूल" ऑब्जेक्ट में कोई विशेषता नहीं है "ascii_uppercase" $ python2.7 pkg/main2.py ट्रेसबैक (सबसे हालिया कॉल अंतिम): फ़ाइल "pkg/main2.py", पंक्ति 3, <मॉड्यूल> प्रिंट string.ascii_uppercase विशेषता त्रुटि: "मॉड्यूल" ऑब्जेक्ट में कोई विशेषता नहीं है "ascii_uppercase" 

साथ ही Python 3.5, साथ या बिना (यह मानते हुए कि प्रिंट कथन दोनों फाइलों में बदल गया है):

< प्री> <कोड> $ python3.5 pkg/main.py ट्रेसबैक (सबसे हालिया कॉल अंतिम): फ़ाइल "pkg/main.py", पंक्ति 2, <मॉड्यूल> प्रिंट (string.ascii_uppercase) में विशेषता त्रुटि: मॉड्यूल "स्ट्रिंग " कोई विशेषता नहीं है "ascii_uppercase" $ python3.5 pkg/main2.py Trac eback (सबसे हालिया कॉल अंतिम): फ़ाइल "pkg/main2.py", पंक्ति 3, <मॉड्यूल> print(string.ascii_uppercase) AttributeError: मॉड्यूल "स्ट्रिंग" में कोई विशेषता नहीं है "ascii_uppercase"

मैंने इसके अन्य रूपों का परीक्षण किया है। string.py के बजाय, मैंने एक खाली मॉड्यूल बनाया है -- string नाम की एक निर्देशिका जिसमें केवल एक खाली __init__.py है - और इसके बजाय main.py से आयात जारी करने के लिए, मेरे पास cd"d से pkg है और सीधे REPL से आयात चलाते हैं। इनमें से कोई भी विविधता नहीं है (न ही उनमें से एक संयोजन) ने उपरोक्त परिणामों को बदल दिया। मैं इसे __future__ निर्देश और पूर्ण आयात के बारे में जो पढ़ा है, उसके साथ मेल नहीं कर सकता।

मुझे ऐसा लगता है कि यह आसानी से समझा जा सकता है निम्नलिखित द्वारा (यह पायथन 2 डॉक्स से है लेकिन यह पायथन 3 के लिए एक ही डॉक्स में स्टेटमेंट अपरिवर्तित रहता है):

sys.path

(...)

जैसा कि प्रोग्राम स्टार्टअप पर शुरू किया गया था, इस सूची का पहला आइटम, path[0], वह निर्देशिका है जिसमें स्क्रिप्ट शामिल है जिसका उपयोग पायथन दुभाषिया को लागू करने के लिए किया गया था। यदि स्क्रिप्ट निर्देशक y उपलब्ध नहीं है (उदाहरण के लिए यदि दुभाषिया को अंतःक्रियात्मक रूप से आमंत्रित किया जाता है या यदि स्क्रिप्ट को मानक इनपुट से पढ़ा जाता है), path[0] खाली स्ट्रिंग है, जो पायथन को मॉड्यूल में खोज करने के लिए निर्देशित करता है वर्तमान निर्देशिका पहले।

तो मैं क्या खो रहा हूँ? __future__ कथन ऐसा क्यों प्रतीत नहीं होता है जो यह कहता है, और दस्तावेज़ीकरण के इन दो खंडों के साथ-साथ वर्णित और वास्तविक व्यवहार के बीच इस विरोधाभास का समाधान क्या है?