পরম বনাম পাইথন মডিউলটির সুস্পষ্ট আপেক্ষিক আমদানি


90

আমি পাইথন অ্যাপ্লিকেশনটিতে প্যাকেজগুলি আমদানির পছন্দের উপায় সম্পর্কে ভাবছি। আমার এই জাতীয় প্যাকেজ কাঠামো রয়েছে:

project.app1.models
project.app1.views
project.app2.models

project.app1.viewsআমদানি project.app1.modelsএবং project.app2.models। এটি করার দুটি উপায় আছে যা মনে আসে।

পরম আমদানি সহ:

import A.A
import A.B.B

বা পিইপি 328 এর সাথে পাইথন 2.5 তে যেমন প্রকাশিত আপেক্ষিক আমদানি রয়েছে :

# explicit relative
from .. import A
from . import B

এটি করার সর্বাধিক পাইথোনিক উপায় কী?


"সুস্পষ্ট আপেক্ষিক" উদাহরণগুলি সিনট্যাক্স ত্রুটি। আপেক্ষিক আমদানি অবশ্যই ফর্মের মধ্যে থাকতে হবে from _ import ..., সুতরাং আপনার উদাহরণগুলি হতে পারে from .. import Aএবংfrom . import B
মাস্ট্রেলিওন

@ মাস্টারলিয়ন ভাল ক্যাচ, আপনি একেবারে ঠিক আছেন! আমি থেকে আমার প্রশ্নের আপডেট import ..Aকরার from .. import A। লক্ষণীয় যে কারও নজরে না আসা পর্যন্ত এটি কেবল 9 বছর সময় নিয়েছিল;)
ড্যানিয়েল হিপার

উত্তর:


56

সম্পূর্ণ আমদানি। পিইপি 8 থেকে:

আন্তঃ-প্যাকেজ আমদানির জন্য আপেক্ষিক আমদানি অত্যন্ত নিরুৎসাহিত। সর্বদা সমস্ত আমদানির জন্য পরম প্যাকেজ পাথটি ব্যবহার করুন। এখনও এখন পিইপি 328 [7] পাইথন 2.5 তে সম্পূর্ণভাবে প্রয়োগ করা হয়েছে, এর সুস্পষ্ট আপেক্ষিক আমদানির স্টাইল সক্রিয়ভাবে নিরুৎসাহিত করা হয়েছে; পরম আমদানি আরও পোর্টেবল এবং সাধারণত আরও পঠনযোগ্য।

সুস্পষ্ট আপেক্ষিক আমদানিগুলি একটি দুর্দান্ত ভাষার বৈশিষ্ট্য (আমার ধারণা) তবে এগুলি নিখুঁত আমদানির মতো প্রায় স্পষ্ট নয়। আরও পঠনযোগ্য ফর্মটি হ'ল:

import A.A
import A.B.B

বিশেষত যদি আপনি বেশ কয়েকটি বিভিন্ন নেমস্পেস আমদানি করেন। আপনি যদি কিছু ভাল লিখিত প্রকল্প / টিউটোরিয়াল দেখে থাকেন যা প্যাকেজগুলির মধ্যে থেকে আমদানি অন্তর্ভুক্ত করে তবে তারা সাধারণত এই স্টাইলটি অনুসরণ করে।

আপনি আরও স্পষ্ট হয়ে উঠতে কয়েকটি অতিরিক্ত কী-স্ট্রোকগুলি ভবিষ্যতে অন্যদের (এবং সম্ভবত আপনি) প্রচুর সময় সাশ্রয় করবে যখন তারা আপনার নাম স্থানটি নির্ধারণ করার চেষ্টা করছে (বিশেষত আপনি যদি 3.x এ স্থানান্তরিত হন তবে কিছু প্যাকেজ নাম পরিবর্তন হয়েছে)।


@ রাফা, "কিছু ভাল লেখা প্রকল্প দেখুন ..." কোন পরামর্শ?
ডেনিস

@ ডেনিস: রাইটভেল্ড হ'ল গুডো ভ্যান রসমের নিজস্ব প্রকল্প, তাই আমি কল্পনা করতে পারি যে এটি দেখার জন্য ভাল জায়গা হবে ( কোড . google.com/p/rietveld )। পাইথন স্ট্যান্ডার্ড লাইব্রেরি এত দুর্দান্ত নয়, প্রচুর কোড কনভেনশন অনুসরণ করে না।
রাফ কেটলার

68
@ রাফা: গাইডোর মতে পিইপি -8 এর সেই অংশটি পুরানো। mail.python.org/pipermail/python-dev/2010-
ব্র্যান্ডন রোডস

13
এই বিবৃতি এখন আর পিইপি -8 এ নেই। এটি এখন জানায় নিখুঁত আমদানির প্রস্তাব দেওয়া হয়, তবে আপেক্ষিক আমদানি একটি গ্রহণযোগ্য বিকল্প।
ড্যানো

6
পরম আমদানিতে আমার যে সমস্যাটি হ'ল তা হল অন্য প্যাকেজের মধ্যে প্যাকেজ ব্যবহার করার সময়। আমার ক্ষেত্রে এটি গিট সাবমডিউল হিসাবে উপস্থিত। এই ক্ষেত্রে, যদিও আমি শীর্ষ-স্তরের প্যাকেজটি আমদানি করতে পারি, তবে এর নীচের যে কোনও প্যাকেজ আমদানি করা যাবে না কারণ তারা পরম আমদানি সহ তাদের নিজস্ব মডিউল খুঁজে পেতে ব্যর্থ হয়। আমি যদি এই নীচের স্তরে আপেক্ষিক আমদানি ব্যবহার করি তবে এটি কেবল কার্যকর।
ডেভিডা

125

পাইথনের আপেক্ষিক আমদানি আর জোরালোভাবে নিরুৎসাহিত করা হয় না, তবে সেই ক্ষেত্রে পরম_আরপোর্ট ব্যবহার করার দৃ strongly় পরামর্শ দেওয়া হয় is

গুইডো নিজেই উদ্ধৃত করে এই আলোচনাটি দেখুন :

"এটি কি বেশিরভাগ historicalতিহাসিক নয়? নতুন আপেক্ষিক-আমদানি সিনট্যাক্স বাস্তবায়িত না হওয়া পর্যন্ত আপেক্ষিক আমদানি নিয়ে বিভিন্ন সমস্যা ছিল। স্বল্পমেয়াদী সমাধানটি সেগুলি ব্যবহার না করার পরামর্শ দেওয়া হয়েছিল। দীর্ঘমেয়াদী সমাধানটি ছিল একটি দ্ব্যর্থহীন বাক্য গঠন কার্যকর করা Now এখন বিরোধী-সুপারিশটি প্রত্যাহার করার সময় এসেছে Of অবশ্যই, ওভারবোর্ড না করেই - আমি এখনও তাদের অর্জিত স্বাদ পাই; তবে তাদের জায়গা রয়েছে have

ওপি সঠিকভাবে পিইপি 328 এর সাথে লিঙ্ক করেছে যা বলে:

বেশ কয়েকটি ব্যবহারের কেস উপস্থাপন করা হয়েছিল, যার মধ্যে সর্বাধিক গুরুত্বপূর্ণ সাব-প্যাকেজগুলি সম্পাদনা না করে বৃহত প্যাকেজগুলির কাঠামো পুনর্বিন্যস্ত করতে সক্ষম হচ্ছে। তদুপরি, প্যাকেজের অভ্যন্তরের কোনও মডিউল আপেক্ষিক আমদানি ছাড়াই সহজে নিজেকে আমদানি করতে পারে না।

পাইথনে আপেক্ষিক আমদানি কখন বা কেন ব্যবহার করতে হবে তা প্রায় সদৃশ প্রশ্ন দেখুন

অবশ্যই এটি এখনও স্বাদের বিষয় হিসাবে দাঁড়িয়েছে। আপেক্ষিক আমদানির সাথে কোড ঘোরানো সহজতর, এটি অপ্রত্যাশিতভাবে জিনিসগুলিও ভেঙে দিতে পারে; এবং আমদানির নামকরণ করা এতটা কঠিন নয়।

পিইপি 328 থেকে নতুন আচরণটি জোর করার জন্য:

from __future__ import absolute_import

এই ক্ষেত্রে, অন্তর্নিহিত আপেক্ষিক আমদানি আর সম্ভব import localfileহবে না (উদাহরণস্বরূপ , কেবলমাত্র আর কাজ করবে না from . import localfile)। পরিষ্কার এবং ভবিষ্যতের প্রমাণ আচরণের জন্য, পরম_পিম্প ব্যবহার করা ভাল।

একটি গুরুত্বপূর্ণ সতর্কতা হ'ল পিইপি 338 এবং পিইপি 366 এর কারণে আপেক্ষিক আমদানিতে পাইথন ফাইলটি মডিউল হিসাবে আমদানি করা দরকার - আপনি কোনও ফাইল.পি চালাতে পারবেন না যার আপেক্ষিক আমদানি রয়েছে বা আপনি একটি পাবেন ValueError: Attempted relative import in non-package

সেরা পদ্ধতির মূল্যায়ন করার সময় এই সীমাবদ্ধতাটি বিবেচনায় নেওয়া উচিত। গাইড কোনও অবস্থাতেই মডিউল থেকে স্ক্রিপ্ট চালানোর বিরুদ্ধে:

আমি এটিতে এবং _______ মেশিনির অন্য কোনও প্রস্তাবিত ট্যুইডলিংয়ে -1 আছি। একমাত্র ব্যবহারের ক্ষেত্রে স্ক্রিপ্টগুলি চলমান বলে মনে হচ্ছে যেগুলি মডিউলটির ডিরেক্টরিতে বাস করে যা আমি সবসময় একটি অ্যান্টিপ্যাটার্ন হিসাবে দেখেছি। আমাকে আমার মন পরিবর্তন করতে আপনাকে আমাকে বোঝাতে হবে যে এটি তা নয়।

বিষয়টি নিয়ে ক্লান্তিকর আলোচনা এসও-তে পাওয়া যাবে; পুনরায়। পাইথন 3 এটি বেশ ব্যাপক:


9
গুডো লিখেছেন যে ২০১০ সালে এবং এটি এখনও পিইপিতে আছে? পিইপিগুলি এত পুরানো হলে আমরা কীভাবে বিশ্বাস করব?
জবাবা

4
পিইপি মার্কিন যুক্তরাষ্ট্রে এই অর্থে যে আপনি জিনিসগুলি সংশোধন করতে পারেন like প্রত্যাখ্যানিত অনেকগুলি পিইপিএসও রয়েছে। পিইপিগুলি হ'ল প্রস্তাব। এগুলি গ্রহণযোগ্য, প্রত্যাখ্যাত বা অপ্রচলিত হতে পারে যার অর্থ প্রায়শই নতুন পিইপি হয় E পিইপি 8 একটি স্টাইল গাইড তাই এটি জায়গায় পরিবর্তিত হতে পারে।
সিপিপিআলনার

4
আমি "একটি প্যাকেজের অভ্যন্তরে কোনও মডিউল সহজেই নিজেকে আমদানি করতে পারে না ..." অংশ সম্পর্কে বিভ্রান্ত am মডিউলগুলি নিজের ইম্পোর্ট করার আগে আমি কখনও শুনিনি।
matiascelasco

4
একটি সম্ভাব্য উদাহরণ @ মটিয়াসেসেলাস্কো: আপনার কাছে যদি foo / bar.py এবং foo / baz.py তবে অন্য কোথাও baz.py থাকে। আপনি যদি বার থেকে foo.bat আমদানি করতে চান তবে আপনি কী আমদানি করছেন তা সম্পর্কে নিশ্চিত হতে পারেন, যেমন। import .baz- যদিও এটি পিইপিতে বর্ণিত অনেক অনুরূপ পরিস্থিতির মধ্যে কেবল একটি সরলতা।
স্টেফানো

আপনার উত্তর তাদের অনুমতি দেওয়ার পরিবর্তনে আলাদাভাবে আলাদা করে না। অন্তর্নিহিত আপেক্ষিক আমদানি কখনই ব্যবহার করা উচিত নয়, তবে সুস্পষ্ট আপেক্ষিক আমদানিগুলি ব্যবহার করা ঠিক। অন্তর্নিহিত আত্মীয় পাইথন 3 থেকে সরানো হয়েছে।
ninMonkey

33

আপেক্ষিক আমদানি কয়েক ডজন অভ্যন্তরীণ আমদানি পরিবর্তন না করে কেবল আপনাকে পরে আপনার প্যাকেজটির নাম পরিবর্তন করতে ছাড়বে না, তবে বৃত্তাকার আমদানি বা নেমস্পেস প্যাকেজগুলির মতো বিষয়গুলির সাথে জড়িত কিছু সমস্যা সমাধানে আমি তাদের সাথে সাফল্যও পেয়েছি, কারণ তারা পাইথনকে "ফেরত পাঠায় না" the শীর্ষ "শীর্ষস্থানীয় নেমস্পেস থেকে আবার পরবর্তী মডিউলটির জন্য অনুসন্ধান শুরু করতে।


4
পাইথন স্টাইল গাইড অনুসারে এটি নিরুৎসাহিত স্টাইল। তারা কঠোরভাবে পঠনযোগ্যতার মেঘ দেয় এবং আপনি যা বোঝেন সেই "সুবিধাবলীর" উপযুক্ত নয়। কোনও সমস্যা সমাধানের জন্য যদি আপেক্ষিক আমদানি ব্যবহার করতে হয় তবে আপনি এটি ভুল করছেন wrong
রাফ কেটলার

14
অন্যান্য উত্তরটিতে তাঁর (ব্র্যান্ডন রোডস) মন্তব্যটি নোট করুন, এমন লিঙ্কের সাহায্যে যা এটি আর নিরুৎসাহিত হয় না।
জন কোম্বস

4
@ রাফেকিটলার আপনি কীভাবে অন্য প্যাকেজের মধ্যে অন্তর্ভুক্ত এমন একটি প্যাকেজে নিখুঁত আমদানি ব্যবহার করবেন তা কীভাবে ব্যাখ্যা করতে পারেন? অভ্যন্তরীণ প্যাকেজটির মধ্যে নিখুঁত আমদানি ব্যর্থ হবে কারণ তারা নতুন শীর্ষ স্তরের সম্পর্কে জানেন না। আপেক্ষিক আমদানি কাজ চালিয়ে যায়। একটি সম্ভবত তর্ক করতে পারে যে প্যাকেজটি প্রথমে অন্যের ভিতরে নেস্ট করা উচিত নয়, তবে কিছু কোড পুনরায় ব্যবহারযোগ্য বলে বোঝানো হয় এবং এটি অনেক ঘটে। প্রচুর পুনঃব্যবহৃত কোড জনসাধারণের জন্য প্যাকেজ করা হয়নি এবং অতএব পৃথক প্যাকেজ হিসাবে সরবরাহ করা হয়নি সুতরাং অ্যাডহক পদ্ধতিগুলি যেমন
ভিসিএস

4
@ মেসোস্কাক আমি সম্মত, কিছু প্যাকেজগুলি সহজেই ইনস্টলযোগ্য হয় না (সেগুলি পাইপে নেই, আপনি ব্যবহার করতে চান না python setup.py installবা python setup.py developযে কারণেই হোক না কেন), সেই ক্ষেত্রে আমি উত্স কোডটি কাঁটাচামচ করি এবং এটি একটি গিট সাবমোডুল হিসাবে যুক্ত করি। যখন এই প্যাকেজগুলি তাদের নিজস্ব প্যাকেজের নামে নিখুঁত আমদানি ব্যবহার করে, তখন তাদের আমদানি ব্যর্থ হয়। একমাত্র সমাধান হ'ল সুস্পষ্ট আপেক্ষিক আমদানি ব্যবহার করা। এটাই আমার মনে হয় উত্সাহ দেওয়া উচিত।
সিএমসিডিগ্রাগনকাই
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.