আমি পাইথনের নিখুঁত আমদানি সম্পর্কিত একটি প্রশ্নের উত্তর দিয়েছি , যা আমি ভেবেছিলাম পাইথন ২.৫ চেঞ্জলগ পড়ার সাথে সাথে পিইপি সহ আমি বুঝতে পেরেছি । যাইহোক, পাইথন 2.5 ইনস্টল করার পরে এবং সঠিকভাবে ব্যবহারের উদাহরণ তৈরি করার চেষ্টা করার পরে from __future__ import absolute_import
আমি বুঝতে পারি যে জিনিসগুলি এত পরিষ্কার নয় so
উপরের লিঙ্কযুক্ত চেঞ্জলগ থেকে সরাসরি, এই বিবৃতিটি পরম আমদানি পরিবর্তনের আমার বোঝার সঠিকভাবে সংক্ষিপ্তসার করেছে:
ধরা যাক আপনার এইরকম একটি প্যাকেজ ডিরেক্টরি রয়েছে:
pkg/ pkg/__init__.py pkg/main.py pkg/string.py
এই নামে একটি প্যাকেজ সংজ্ঞায়িত
pkg
ধারণকারীpkg.main
এবংpkg.string
submodules।মেইন.পি মডিউলটিতে কোডটি বিবেচনা করুন। যদি বিবৃতি কার্যকর করে তবে কী হবে
import string
? পাইথন ২.৪ এবং তার আগে, এটি প্যাকেজ ডিরেক্টরিতে প্রথমে আপেক্ষিক আমদানি সম্পাদন করবে, 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 তে, আপনি
import
কোনওfrom __future__ import absolute_import
নির্দেশিকা ব্যবহার করে নিখুঁত আমদানিতে আচরণের স্যুইচ করতে পারেন । এই পরম-আমদানি আচরণটি ভবিষ্যতের সংস্করণে সম্ভবত ডিফল্ট হয়ে উঠবে (সম্ভবত পাইথন ২.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'
এই সুন্দর স্পষ্টাস্পষ্টি বিবৃতি যে contradicts import string
হবে সবসময় পরম আমদানির সক্রিয় এসটিডি-liberal এর সংক্ষিপ্ত রূপ সংস্করণ খুঁজে পেতে। আরও কি, পরম্পরায় আমদানিগুলি "নতুন ডিফল্ট" আচরণে পরিণত হওয়ার তফসিল সত্ত্বেও, আমি পাইথন ২.7 উভয়ই __future__
নির্দেশের সাথে বা ছাড়াই এই একই সমস্যায় পড়েছি :
$ 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'
পাশাপাশি পাইথন ৩.৫ এর সাথে বা তার বাইরেও (ধরে নিবেন 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__
বিবৃতি আপাতদৃষ্টিতে না এটি যা বলে, এবং কি, ডকুমেন্টেশন এই দুই বিভাগগুলির মধ্যে এই দ্বন্দ্বের রেজল্যুশন হিসাবে ভাল হিসাবে বর্ণনা মধ্যে এবং প্রকৃত আচরণ?