मैंने पायथन में पूर्ण आयात के संबंध में एक सवाल का जवाब दिया है, जो मुझे लगा कि मैं पायथन 2.5 चैंज को पढ़ने और पीईपी के साथ पढ़ने के आधार पर समझ गया हूं । हालांकि, पायथन 2.5 को स्थापित करने और ठीक से उपयोग करने का एक उदाहरण शिल्प करने का प्रयास करने पर from __future__ import absolute_import
, मुझे लगता है कि चीजें इतनी स्पष्ट नहीं हैं।
ऊपर दिए गए चैंज से सीधे, इस कथन ने पूर्ण रूप से आयात परिवर्तन की मेरी समझ को संक्षेप में प्रस्तुत किया:
मान लें कि आपके पास इस तरह एक पैकेज निर्देशिका है:
pkg/ pkg/__init__.py pkg/main.py pkg/string.py
इस नाम के एक पैकेज को परिभाषित करता है
pkg
युक्तpkg.main
औरpkg.string
submodules।मेनफ्रेम मॉड्यूल में कोड पर विचार करें। यदि यह कथन निष्पादित करता है तो क्या होता है
import string
? पायथन 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
निम्नलिखित कोड शामिल हैं:
import string
print string.ascii_uppercase
जैसा कि अपेक्षित था, पायथन 2.5 के साथ इसे चलाना विफल रहता है AttributeError
:
$ python2.5 pkg/main.py
Traceback (most recent call last):
File "pkg/main.py", line 2, in <module>
print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'
हालाँकि, 2.5 चैंज में आगे, हम इसे पाते हैं (जोर जोड़ा):
पायथन 2.5 में, आप
import
एकfrom __future__ import absolute_import
निर्देश का उपयोग करके पूर्ण व्यवहार पर स्विच कर सकते हैं । यह पूर्ण-आयात व्यवहार भविष्य के संस्करण (शायद पायथन 2.7) में डिफ़ॉल्ट हो जाएगा। एक बार पूर्ण आयात डिफ़ॉल्ट होने के बाद,import string
हमेशा मानक लाइब्रेरी का संस्करण मिलेगा।
मैंने इस प्रकार बनाया pkg/main2.py
, main.py
लेकिन अतिरिक्त भविष्य के आयात के निर्देश के समान। अब यह इस तरह दिखता है:
from __future__ import absolute_import
import string
print string.ascii_uppercase
पायथन 2.5 के साथ इसे चलाना, हालांकि ... के साथ विफल रहता है AttributeError
:
$ python2.5 pkg/main2.py
Traceback (most recent call last):
File "pkg/main2.py", line 3, in <module>
print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'
यह सुंदर साफ बयान है कि विपरीत import string
होगा हमेशा पूर्ण आयात के साथ सक्षम एसटीडी-लिब संस्करण पाते हैं। चेतावनी के बावजूद कि पूर्ण आयात "नया डिफ़ॉल्ट" व्यवहार बनने वाला है, मैंने __future__
निर्देश के साथ या उसके बिना पायथन 2.7 दोनों का उपयोग करके इस समस्या को मारा :
$ python2.7 pkg/main.py
Traceback (most recent call last):
File "pkg/main.py", line 2, in <module>
print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'
$ python2.7 pkg/main2.py
Traceback (most recent call last):
File "pkg/main2.py", line 3, in <module>
print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'
पायथन 3.5 के साथ, इसके साथ या उसके बिना ( print
कथन को दोनों फाइलों में बदला गया है):
$ python3.5 pkg/main.py
Traceback (most recent call last):
File "pkg/main.py", line 2, in <module>
print(string.ascii_uppercase)
AttributeError: module 'string' has no attribute 'ascii_uppercase'
$ python3.5 pkg/main2.py
Traceback (most recent call last):
File "pkg/main2.py", line 3, in <module>
print(string.ascii_uppercase)
AttributeError: module 'string' has no attribute 'ascii_uppercase'
मैंने इसके अन्य रूपों का परीक्षण किया है। इसके बजाय string.py
, मैंने एक खाली मॉड्यूल बनाया है - string
केवल एक खाली नाम वाली एक निर्देशिका __init__.py
- और इसके बजाय से आयात जारी करने के बजाय main.py
, मेरे पास हैcd
pkg
REPL से सीधे आयात करने और चलाने के लिए है। न तो इन विविधताओं (और न ही उनमें से एक संयोजन) ने उपरोक्त परिणामों को बदल दिया। मैं इस बारे में जो मैंने पढ़ा है उसके साथ सामंजस्य नहीं बना सकता__future__
निर्देश और पूर्ण आयात के ।
ऐसा लगता है कि यह निम्नलिखित द्वारा आसानी से पता लगाया जा सकता है (यह पायथन 2 डॉक्स से है लेकिन यह कथन पायथन 3 के लिए एक ही डॉक्स में अपरिवर्तित है):
sys.path
(...)
जैसा कि प्रोग्राम स्टार्टअप पर शुरू किया गया था, इस सूची का पहला आइटम,
path[0]
स्क्रिप्ट युक्त निर्देशिका है जिसका उपयोग पायथन इंटरप्रेटर को लागू करने के लिए किया गया था। यदि स्क्रिप्ट निर्देशिका उपलब्ध नहीं है (उदाहरण के लिए यदि इंटरप्रेन्योर को अंतःक्रियात्मक रूप से आमंत्रित किया जाता है या यदि स्क्रिप्ट को मानक इनपुट से पढ़ा जाता है),path[0]
तो खाली स्ट्रिंग है, जो पहले पायथन को वर्तमान निर्देशिका में खोज मॉड्यूल को निर्देशित करता है।
तो मुझे क्या याद आ रही है? __future__
बयान क्यों प्रतीत होता है कि यह क्या कहता है, और प्रलेखन के इन दो वर्गों के बीच और साथ ही वर्णित और वास्तविक व्यवहार के बीच इस विरोधाभास का क्या संकल्प है?