আমদানি বিবৃতি সর্বদা একটি মডিউল শীর্ষে থাকা উচিত?


403

পিইপি 08 বলেছেন:

আমদানি সর্বদা ফাইলের শীর্ষে রাখা হয় কেবল কোনও মডিউল মন্তব্য এবং ডকাস্ট্রিংয়ের পরে এবং মডিউল গ্লোবাল এবং ধ্রুবকগুলির আগে।

তবে আমি যে শ্রেণি / পদ্ধতি / ফাংশনটি আমদানি করছি তা যদি কেবল বিরল ক্ষেত্রে ব্যবহার করা হয়, অবশ্যই যখন প্রয়োজন হয় তখন আমদানি করা আরও দক্ষ হয়?

এটি না:

class SomeClass(object):

    def not_often_called(self)
        from datetime import datetime
        self.datetime = datetime.now()

এর চেয়ে বেশি দক্ষ?

from datetime import datetime

class SomeClass(object):

    def not_often_called(self)
        self.datetime = datetime.now()

উত্তর:


283

মডিউল আমদানি বেশ দ্রুত, তবে তাত্ক্ষণিক নয়। এই যে মানে:

  • মডিউলটির শীর্ষে আমদানি করা ভাল, কারণ এটি একটি তুচ্ছ ব্যয় যা কেবল একবারই প্রদান করা হয়।
  • কোনও ফাংশনের মধ্যে আমদানি স্থাপনের ফলে সেই ফাংশনে কলগুলি বেশি সময় নিতে পারে।

সুতরাং যদি আপনি দক্ষতা সম্পর্কে যত্নশীল হন, আমদানিগুলি শীর্ষে রাখুন। শুধু তাদের একটি ফাংশন সরাতে যদি আপনার প্রোফাইলিং অনুষ্ঠান সাহায্য করবে (আপনি করেনি প্রোফাইল দেখতে যেখানে সেরা পারফরম্যান্সের উন্নতি করতে, ডান ??)


অলস আমদানি করতে দেখা সবচেয়ে ভাল কারণগুলি হ'ল:

  • Libraryচ্ছিক গ্রন্থাগার সমর্থন। যদি আপনার কোডে একাধিক পাথ থাকে যা বিভিন্ন গ্রন্থাগার ব্যবহার করে, anচ্ছিক লাইব্রেরি ইনস্টল না থাকলে ভাঙবেন না।
  • ইন __init__.pyএকটি প্লাগইন, আমদানি করা হতে পারে কিন্তু আসলে ব্যবহার করা হয়। উদাহরণগুলি হ'ল বাজার প্লাগইন, যা bzrlibঅলস-লোডিং ফ্রেমওয়ার্ক ব্যবহার করে।

17
জন, এটি একটি সম্পূর্ণ তাত্ত্বিক প্রশ্ন তাই আমার প্রোফাইলে কোনও কোড নেই। অতীতে আমি সর্বদা পিইপি অনুসরণ করেছি, তবে আমি আজ এমন কিছু কোড লিখেছি যা আমাকে ভাবতে পেরেছিল যে এটি করা সঠিক জিনিস ছিল কিনা। আপনার সাহায্যের জন্য ধন্যবাদ.
অ্যাডাম জে ফারস্টার

43
> আমদানি কোনও ফাংশনের মধ্যে রাখার ফলে সেই ফাংশনে কলগুলি বেশি সময় নিতে পারে। আসলে, আমি মনে করি এই ব্যয়টি কেবল একবারের জন্য প্রদান করা হবে। আমি পড়েছি পাইথন আমদানি করা মডিউলটিকে ক্যাশে করে যাতে এটি আবার আমদানির জন্য কেবল সর্বনিম্ন ব্যয় হয়।
মল্টেনফর্ম

24
@ অ্যালহাউরহ্যাকস পাইথন মডিউলটি পুনরায় আমদানি করবে না, তবে মডিউলটি সিস.মোডিয়ুলস / ইত্যাদিতে রয়েছে কিনা তা দেখার জন্য এখনও কয়েকটি নির্দেশাবলী পালন করতে হবে
জন মিলিকিন

24
-1। কোনও ফাংশনে আমদানি করা অগত্যা এটি আরও বেশি সময় নেয়। অন্য প্রশ্নের আমার উত্তর দেখুন দয়া করে ।
অ্যারোনস্টার্লিং

4
একটি ব্যবহারের ক্ষেত্রে বিজ্ঞপ্তি আমদানি এড়ানো হয় (সাধারণত বুদ্ধিমান হয় না তবে কখনও কখনও এটি উপযুক্ত হয়)। কখনও কখনও মডিউল এম 1 এর ক্লাস এ ক্লাস বিতে একটি পদ্ধতি কল করে মডিউল এম 2 এর মধ্যে যা ক্লাস এ এর ​​আরও একটি উদাহরণ তৈরি করে যদি ক্লাস বিতে যে পদ্ধতিটি ক্লাস এ এর ​​একটি উদাহরণ তৈরি করে তা যদি কেবলমাত্র ফাংশন কার্যকর করার পরে আমদানি চালিত হয় যা একটি উদাহরণ তৈরি করে, বিজ্ঞপ্তি আমদানি এড়ানো হয়।
স্যাম সুইভেনজোরগ্রিস্টিয়েনসেনসেন

80

কোনও ফাংশনের অভ্যন্তরে আমদানি বিবৃতি স্থাপন করা বিজ্ঞপ্তি নির্ভরতা রোধ করতে পারে। উদাহরণস্বরূপ, যদি আপনার কাছে দুটি মডিউল, এক্স.পি এবং ওয়াইপি থাকে এবং তাদের উভয়কে একে অপরকে আমদানি করতে হয় তবে আপনি যখন অসীম লুপ তৈরির একটি মডিউল আমদানি করেন তখন এটি একটি বিজ্ঞপ্তি নির্ভরতা ঘটায়। আপনি যদি কোনও মডিউলে আমদানি বিবৃতিটি সরিয়ে থাকেন তবে ফাংশন না বলা পর্যন্ত এটি অন্য মডিউলটি আমদানি করার চেষ্টা করবে না এবং সেই মডিউলটি ইতিমধ্যে আমদানি হয়ে যাবে, সুতরাং অসীম লুপ নেই। আরও পড়ার জন্য এখানে পড়ুন - effbot.org/zone/import-confusion.htm


3
হ্যাঁ তবে একজন নির্ভরশীল নরকে যেতে পারে।
আইজিনিইন

8
যদি দুটি মডিউল একে অপরকে আমদানি করা প্রয়োজন, কোড সহ কিছু মারাত্মক ভুল।
আন্না

অবজেক্ট ওরিয়েন্টেড প্রোগ্রামিং প্রায়শই আমাকে বিজ্ঞপ্তি নির্ভরতার দিকে নিয়ে যায়। একটি প্রাণবন্ত অবজেক্ট শ্রেণি বিভিন্ন মডিউলগুলিতে আমদানি করা যেতে পারে। এই অবজেক্টটির নিজস্ব কাজ সম্পাদন করার জন্য, সেই মডিউলগুলির একটি বা একাধিকের কাছে পৌঁছানোর প্রয়োজন হতে পারে। এটি এড়ানোর উপায় রয়েছে যেমন ফাংশন আরোগুলির মাধ্যমে অবজেক্টে ডেটা প্রেরণ, এটি অন্য মডিউলে অ্যাক্সেস করার অনুমতি দেয়। কিন্তু এমন সময় আছে যখন এটি করা ওওপি-র কাছে খুব স্ব-স্বজ্ঞাত বোধ করে (বাহ্যিক বিশ্বের কীভাবে এটি সেই কার্যটিতে কার্য সম্পাদন করে তা জানার দরকার নেই)।
রবার্ট

4
যখন এক্সের ওয়াই এবং ওয়াইয়ের এক্স দরকার হয়, সেগুলি হয় একই ধারণার দুটি অংশ (যেমন একসাথে সংজ্ঞায়িত করা উচিত) অথবা বিমূর্ত বিমূর্ততা রয়েছে।
GLRoman

59

আমি মডিউলটির শীর্ষে না গিয়ে সমস্ত আমদানিগুলি যে ফাংশনগুলি ব্যবহার করে সেগুলিতে রাখার অনুশীলন আমি গ্রহণ করেছি।

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

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

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

আমি সাধারণত চেকের sysভিতরে আমদানি রাখি if __name__=='__main__'এবং তারপরে sys.argv[1:]একটি main()ফাংশনে আর্গুমেন্টগুলি (পছন্দ করি ) পাস করি । এটি আমাকে এমন mainপ্রসঙ্গে ব্যবহার করতে দেয় যেখানে sysআমদানি করা হয়নি।


4
অনেক আইডিই আপনার পক্ষে আপনার ফাইলটিতে প্রয়োজনীয় মডিউলগুলি অনুকূল করে এবং স্বয়ংক্রিয়ভাবে আমদানি করে কোডটির রিফ্যাক্টরিংটিকে সহজ করে দেয়। বেশিরভাগ ক্ষেত্রে পাইচার্ম এবং অ্যাকলিপস আমার জন্য সঠিক সিদ্ধান্ত নিয়েছে। আমি বাজি দিয়ে বলি ইমাস বা ভিআইএম-তে একই আচরণ পাওয়ার একটা উপায় আছে।
brent.payne

3
গ্লোবাল নেমস্পেসে যদি একটি বিবৃতিটির ভিতরে একটি আমদানি এখনও বৈশ্বিক আমদানি। এটি আর্গুমেন্টগুলি মুদ্রণ করবে (পাইথন 3 ব্যবহার করে): def main(): print(sys.argv); if True: import sys; main();আপনাকে if __name__=='__main__'একটি নতুন নেমস্পেস তৈরি করতে কোনও ফাংশনে আবদ্ধ করতে হবে।
ডারসিনন

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

@ খারাপ দিকটি হ'ল অনেক অজগর মানুষ এটিকে ঘৃণা করে কারণ আপনি পিপ কোডেক্স লঙ্ঘন করেছেন। আপনাকে আপনার দলের সদস্যদের বোঝাতে হবে। পারফরম্যান্স পেনাল্টি সর্বনিম্ন is কখনও কখনও এটি আরও দ্রুত হয়, stackoverflow.com/a/4789963/362951 দেখুন
মিট করুন

আমি যেখানে আমদানিগুলি সেগুলি ব্যবহার করি তার কাছাকাছি রাখার জন্য রিফ্যাক্টরিংয়ের জন্য এটি অত্যন্ত দরকারী। এত বেশি সময় শীর্ষে এবং পিছনে স্ক্রোল করার দরকার নেই। আমি পাইচার্ম বা উইং আইডির মতো আইডিই ব্যবহার করি এবং তাদের রিফ্যাক্টরিংও ব্যবহার করি তবে আমি সর্বদা তাদের উপর নির্ভর করতে চাই না। এই বিকল্প আমদানি শৈলীর সাথে অন্য মডিউলে ফাংশনগুলি সরানো অনেক সহজ হয়ে যায়, ফলস্বরূপ আমি আরও বেশি রিফ্যাক্টর করি।
এমআইটি

39

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

প্রথমত, আপনি ফর্মের ইউনিট পরীক্ষা সহ একটি মডিউল পেতে পারেন:

if __name__ == '__main__':
    import foo
    aa = foo.xyz()         # initiate something for the test

দ্বিতীয়ত, আপনার শর্তসাপেক্ষে রানটাইমে কিছু আলাদা মডিউল আমদানি করার প্রয়োজন থাকতে পারে।

if [condition]:
    import foo as plugin_api
else:
    import bar as plugin_api
xx = plugin_api.Plugin()
[...]

সম্ভবত অন্যান্য পরিস্থিতি রয়েছে যেখানে আপনি কোডের অন্যান্য অংশে আমদানি করতে পারেন।


14

প্রথম রূপটি প্রকৃতপক্ষে দ্বিতীয়টির চেয়ে বেশি কার্যকর যখন ফাংশনটি শূন্য বা একবার বলা হয়। দ্বিতীয় এবং পরবর্তী অনুরোধগুলির সাথে, তবে "প্রতিটি কল আমদানি করুন" পদ্ধতিটি আসলে কম দক্ষ। একটি অলস-লোডিং কৌশলের জন্য এই লিঙ্কটি দেখুন যা "অলস আমদানি" করে উভয় পদ্ধতির সর্বোত্তম সমন্বয় করে।

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

যুক্ত দ্রষ্টব্য: আয়রনপাইথনে সিপিথনের তুলনায় আমদানি কিছুটা ব্যয়বহুল হতে পারে কারণ কোডটি মূলত আমদানি হওয়ার কারণে সংকলিত হচ্ছে।


1
এটি সত্য নয় যে প্রথমটি আরও ভাল অভিনয় করে: wiki.python.org/moin/PythonSpeed/…
জেসন বেকার

পদ্ধতিটি কখনই ডাকা না হলে এটি আরও ভাল করে তোলে কারণ আমদানি কখনই ঘটে না।
কর্ট হ্যাগেনলোচার

সত্য, তবে পদ্ধতিটি যদি একাধিকবার বলা হয় তবে এটি আরও খারাপ কাজ করে। এবং তাত্ক্ষণিকভাবে মডিউলটি আমদানি না করে যে পারফরম্যান্সের সুবিধা পাবেন তা বেশিরভাগ ক্ষেত্রে নগণ্য। ব্যতিক্রমগুলি যদি মডিউলটি খুব বড় হয় বা এই ধরণের ফাংশনগুলির প্রচুর পরিমাণ থাকে would
জেসন বেকার

আয়রন পাইথন বিশ্বে প্রাথমিক আমদানি সিপিথনের তুলনায় অনেক বেশি ব্যয়বহুল;)। আপনার লিঙ্কে "অলস আমদানি" উদাহরণটি সম্ভবত সেরা সামগ্রিক জেনেরিক সমাধান।
কর্ট হ্যাগেনলোচার

আমি আশা করি আপনার আপত্তি নেই, তবে আমি এটি আপনার পোস্টে সম্পাদনা করেছি। এটি জানতে সহায়ক তথ্য।
জেসন বেকার

9

কার্ট একটি ভাল পয়েন্ট দেয়: দ্বিতীয় সংস্করণটি আরও স্পষ্ট এবং পরে এবং অপ্রত্যাশিতভাবে লোডের সময় ব্যর্থ হবে।

সাধারণত আমি লোডিং মডিউলগুলির দক্ষতার বিষয়ে চিন্তা করি না, কারণ এটি (ক) বেশ দ্রুত এবং (খ) বেশিরভাগই কেবল স্টার্টআপে ঘটে।

যদি আপনাকে অপ্রত্যাশিত সময়ে হেভিওয়েট মডিউলগুলি লোড করতে হয়, তবে সম্ভবত __import__ফাংশনটি দিয়ে এগুলি গতিশীলভাবে লোড করা এবং ব্যতিক্রমগুলি ধরা নিশ্চিত হওয়া ImportErrorএবং যুক্তিসঙ্গত পদ্ধতিতে পরিচালনা করতে আরও বোধগম্য হয়।


8

আমি সামনের দিকে খুব বেশি মডিউল লোড করার দক্ষতা নিয়ে চিন্তা করব না। মডিউলটি তোলা স্মৃতি খুব বড় হবে না (এটি যথেষ্ট পরিমাণে মডুলার ধরে নিলে) এবং প্রারম্ভিক ব্যয়টি নগন্য হবে igible

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

কোডটির অন্য কোনও জায়গায় কোনও মডিউল আমদানির একটি ভাল কারণ হ'ল এটি যদি কোনও ডিবাগিং বিবৃতিতে ব্যবহৃত হয়।

উদাহরণ স্বরূপ:

do_something_with_x(x)

আমি এটি দিয়ে এটি ডিবাগ করতে পারি:

from pprint import pprint
pprint(x)
do_something_with_x(x)

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

আমি সামনের দিকে খুব বেশি মডিউল লোড করার দক্ষতা নিয়ে চিন্তা করব না। মডিউলটি তোলা স্মৃতি খুব বড় হবে না (এটি যথেষ্ট পরিমাণে মডুলার ধরে নিলে) এবং প্রারম্ভিক ব্যয়টি নগন্য হবে igible


আমরা মডিউল (আমার মেশিনে) প্রারম্ভকালীন ব্যয়ের দশ মাইলসেকেন্ডের কথা বলছি। এটি সর্বদা নগণ্য নয়, যেমন যদি এটি কোনও ব্যবহারকারী ক্লিকের জন্য কোনও ওয়েব অ্যাপ্লিকেশনটির প্রতিক্রিয়াটিকে প্রভাবিত করে।
এভেজেনি সার্জিভ

6

এটি একটি ট্রেডঅফ, যা কেবল প্রোগ্রামারই সিদ্ধান্ত নিতে পারে।

কেস 1 প্রয়োজন অবধি ডেটটাইম মডিউলটি আমদানি না করে (এবং যে কোনও প্রারম্ভিকের প্রয়োজন হতে পারে) প্রয়োজন না করে কিছু মেমরি এবং প্রারম্ভকালীন সময় সাশ্রয় করে। দ্রষ্টব্য যে কেবল যখন ডাকা হয় তখন আমদানি করা মানে প্রতিবার যখন ডাকা হয় তখন এটি করাও তাই প্রথম বারের পরে প্রতিটি কল এখনও আমদানি করার অতিরিক্ত ওভারহেড ব্যয় করে।

কেস 2 পূর্বে ডেটটাইম আমদানি করে কিছু কার্যকরকরণের সময় এবং অলসতা বাঁচায় যাতে না_ফটেন_ক্যালড () যখন ডাকা হয় তখন আরও দ্রুত ফিরে আসবে এবং প্রতিটি কলটিতে আমদানির ওভারহেড ব্যয় না করে।

দক্ষতা ছাড়াও, যদি আমদানি বিবৃতিগুলি ... সামনে থাকে তবে সামনের দিকে মডিউল নির্ভরতা দেখা সহজ। কোডে এগুলিকে লুকিয়ে রাখলে কোন মডিউলগুলির উপর নির্ভর করে সহজেই এটি খুঁজে পাওয়া আরও কঠিন হয়ে উঠবে।

ব্যক্তিগতভাবে আমি ইউনিট পরীক্ষার মতো জিনিসগুলি এবং আমি সর্বদা লোড করতে চাই না এমন জিনিসগুলি ব্যতীত সাধারণত পিইপি অনুসরণ করি কারণ আমি জানি তারা পরীক্ষার কোড ব্যতীত ব্যবহার করা যাচ্ছে না।


2
-1। আমদানির প্রধান ওভারহেড কেবল প্রথমবারেই ঘটে। মডিউলটি অনুসন্ধান sys.modulesকরার জন্য ব্যয়টি কেবলমাত্র বিশ্বব্যাপী নামের পরিবর্তে স্থানীয় নামের সন্ধানে সঞ্চয় দ্বারা সহজেই অফসেট করা যায়।
অ্যারোনস্টার্লিং

6

এখানে একটি উদাহরণ যেখানে সমস্ত আমদানি একেবারে শীর্ষে রয়েছে (এটি করার জন্য আমার কেবলমাত্র সময় প্রয়োজন)। আমি আন * এক্স এবং উইন্ডোজ উভয় ক্ষেত্রেই একটি সাবপ্রসেস বন্ধ করতে সক্ষম হতে চাই।

import os
# ...
try:
    kill = os.kill  # will raise AttributeError on Windows
    from signal import SIGTERM
    def terminate(process):
        kill(process.pid, SIGTERM)
except (AttributeError, ImportError):
    try:
        from win32api import TerminateProcess  # use win32api if available
        def terminate(process):
            TerminateProcess(int(process._handle), -1)
    except ImportError:
        def terminate(process):
            raise NotImplementedError  # define a dummy function

(পর্যালোচনা: জন মিলিকিন কী বলেছেন।)


6

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

from foo import bar
from baz import qux
# Note: datetime is imported in SomeClass below

4

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

পাঠযোগ্যতার জন্য যুক্তির সাথে সেই তথ্যটি দ্বিগুণ করুন এবং আমি বলব যে মডিউল স্কোপে আমদানি বিবৃতি থাকা ভাল।


4

কেবল মো এর উত্তর এবং মূল প্রশ্নটি সম্পূর্ণ করতে :

যখন আমাদের বিজ্ঞপ্তি নির্ভরতাগুলি মোকাবেলা করতে হবে তখন আমরা কিছু "কৌশল" করতে পারি। ধরে নিই আমরা মডিউলগুলি a.pyনিয়ে কাজ করছি এবং যথাক্রমে b.pyএতে x()এবং বি রয়েছে y()। তারপর:

  1. আমরা from importsমডিউলের নীচে একটিকে সরাতে পারি ।
  2. from importsআমদানি প্রয়োজন এমন ফাংশন বা পদ্ধতির অভ্যন্তরে আমরা একটিটিকে সরাতে পারি (এটি সর্বদা সম্ভব নয়, কারণ আপনি এটি বেশ কয়েকটি জায়গা থেকে ব্যবহার করতে পারেন)।
  3. আমরা দু'জনের মধ্যে একটির from importsমতো দেখতে আমদানি করতে পারি:import a

সুতরাং, উপসংহারে। আপনি যদি বিজ্ঞপ্তি নির্ভরতা নিয়ে কাজ না করে এবং এড়ানোর জন্য কোনও ধরণের কৌশল অবলম্বন না করে থাকেন তবে এই প্রশ্নের অন্য উত্তরে ইতিমধ্যে ব্যাখ্যা করা কারণগুলির কারণে আপনার সমস্ত আমদানি শীর্ষে রাখাই ভাল। এবং দয়া করে, এই "কৌশলগুলি" করার সময় কোনও মন্তব্য অন্তর্ভুক্ত থাকে, এটি সর্বদা স্বাগত! :)


4

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

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


4

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

আপনি যদি শীর্ষে আমদানি করেন তবে আপনি লোড হিট নেন তা যাই হোক না কেন। এটি বেশ ছোট, তবে সাধারণত মিলিসেকেন্ডে, ন্যানোসেকেন্ডে নয়।

আপনি যদি একটি ফাংশন (গুলি) মধ্যে আমদানি, তাহলে আপনি শুধুমাত্র হিট লোড নিতে যদি এবং যখন সেই কর্ম এক প্রথম বলা হয়। অনেকে উল্লেখ করেছেন যে, যদি এটি কিছু না ঘটে তবে আপনি লোডের সময় বাঁচান। কিন্তু যদি ফাংশন (গুলি) অনেক নামক পেতে, আপনি একটি (পরীক্ষণ এটি জন্য যদিও অনেক ছোট হিট পুনরাবৃত্তি নেওয়া হয়েছে লোড করা হয়েছে; না আসলে পুনরায় লোড হচ্ছে)। অন্যদিকে, @ অ্যারোনাস্টারলিং হিসাবে আপনিও কিছুটা বাঁচাতে পারেন কারণ কোনও ফাংশনের মধ্যে আমদানি ফাংশনটিকে পরে নামটি সনাক্ত করতে কিছুটা দ্রুত স্থানীয় ভেরিয়েবল লুকআপ ব্যবহার করতে দেয় ( http://stackoverflow.com/questions/477096/python- আমদানি কোডিং-স্টাইল / 4789963 # 4789963 )।

এখানে একটি সাধারণ পরীক্ষার ফলাফল যা কোনও ফাংশনের অভ্যন্তর থেকে কয়েকটি জিনিস আমদানি করে। রিপোর্ট করা সময়গুলি (২.৩ গিগাহার্টজ ইন্টেল কোর আই on এর পাইথন ২.7.১৪ এ) নীচে দেখানো হয়েছে (দ্বিতীয় কলটি পরবর্তী কলগুলির চেয়ে বেশি গ্রহণ করা সামঞ্জস্যপূর্ণ বলে মনে হচ্ছে, যদিও আমি জানি না)।

 0 foo:   14429.0924 µs
 1 foo:      63.8962 µs
 2 foo:      10.0136 µs
 3 foo:       7.1526 µs
 4 foo:       7.8678 µs
 0 bar:       9.0599 µs
 1 bar:       6.9141 µs
 2 bar:       7.1526 µs
 3 bar:       7.8678 µs
 4 bar:       7.1526 µs

কোড:

from __future__ import print_function
from time import time

def foo():
    import collections
    import re
    import string
    import math
    import subprocess
    return

def bar():
    import collections
    import re
    import string
    import math
    import subprocess
    return

t0 = time()
for i in xrange(5):
    foo()
    t1 = time()
    print("    %2d foo: %12.4f \xC2\xB5s" % (i, (t1-t0)*1E6))
    t0 = t1
for i in xrange(5):
    bar()
    t1 = time()
    print("    %2d bar: %12.4f \xC2\xB5s" % (i, (t1-t0)*1E6))
    t0 = t1

রানটাইমের পরিবর্তনগুলি সম্ভবত লোডের প্রতিক্রিয়াতে সিপিইউ ফ্রিকোয়েন্সি স্কেলিংয়ের কারণে। সিপিইউ ঘড়ির গতি বাড়িয়ে তুলতে ব্যস্ত কাজের দ্বিতীয়টির সাথে গতি পরীক্ষা শুরু করা ভাল।
হান-কোয়াং নিনিহুইস

3

আমি সম্পূর্ণ উত্তর দেওয়ার জন্য আগ্রহী নই, কারণ অন্যরা ইতিমধ্যে এটি খুব ভাল করে ফেলেছে। আমি কেবলমাত্র একটি ব্যবহারের ক্ষেত্রে উল্লেখ করতে চাই যখন আমি ফাংশনগুলির মধ্যে মডিউলগুলি আমদানি করতে বিশেষভাবে দরকারী মনে করি। আমার অ্যাপ্লিকেশনটি পাইগন প্যাকেজ এবং প্লাগইন হিসাবে নির্দিষ্ট স্থানে মডিউলগুলি ব্যবহার করে। অ্যাপ্লিকেশন প্রারম্ভকালে, অ্যাপ্লিকেশনটি সমস্ত মডিউলটির মধ্যে অবস্থান করে এবং সেগুলি আমদানি করে, তারপরে এটি মডিউলগুলির ভিতরে দেখায় এবং যদি এটি প্লাগিনগুলির জন্য কিছু মাউন্ট পয়েন্টগুলি খুঁজে পায় (আমার ক্ষেত্রে এটি একটি নির্দিষ্ট বেস শ্রেণীর একটি সাবক্লাস যা একটি অনন্য রয়েছে আইডি) এটি তাদের নিবন্ধভুক্ত করে। প্লাগইনগুলির সংখ্যা বড় (এখন কয়েক ডজন, তবে ভবিষ্যতে সম্ভবত কয়েক শতাধিক) এবং সেগুলির প্রতিটি খুব কমই ব্যবহৃত হয়। আমার প্লাগইন মডিউলগুলির শীর্ষে তৃতীয় পক্ষের গ্রন্থাগারগুলির আমদানি করা অ্যাপ্লিকেশন প্রারম্ভের সময় কিছুটা জরিমানা ছিল। বিশেষত কিছু তৃতীয় পক্ষের লাইব্রেরিগুলি আমদানি করতে ভারী হয় (উদাহরণস্বরূপ আমদানি করা এমনকি ইন্টারনেটের সাথে সংযোগ স্থাপনের চেষ্টা করে এবং এমন কিছু ডাউনলোড করার চেষ্টা করে যা শুরুতে প্রায় এক সেকেন্ড যোগ করেছিল)। প্লাগিনগুলিতে আমদানিগুলি (কেবলমাত্র তাদের ব্যবহৃত ফাংশনগুলিতে কল করা) অনুকূলকরণের মাধ্যমে আমি প্রারম্ভটি 10 ​​সেকেন্ড থেকে প্রায় 2 সেকেন্ডে সঙ্কুচিত করতে সক্ষম হয়েছি। এটি আমার ব্যবহারকারীদের জন্য একটি বড় পার্থক্য।

সুতরাং আমার উত্তর হ'ল না, আমদানি সর্বদা আপনার মডিউলগুলির শীর্ষে রাখবেন না।


3

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


1

কোনও ফাংশনের অভ্যন্তরে ভেরিয়েবলগুলি / স্থানীয় স্কোপিং আমদানি করে পারফরম্যান্স লাভ হতে পারে। এটি ফাংশনের অভ্যন্তরে আমদানিকৃত জিনিসগুলির ব্যবহারের উপর নির্ভর করে। আপনি যদি বহুবার লুপ করেন এবং একটি মডিউল গ্লোবাল অবজেক্টে অ্যাক্সেস করেন তবে এটিকে স্থানীয় হিসাবে আমদানি সহায়তা করতে পারে।

test.py

X=10
Y=11
Z=12
def add(i):
  i = i + 10

runlocal.py

from test import add, X, Y, Z

    def callme():
      x=X
      y=Y
      z=Z
      ladd=add 
      for i  in range(100000000):
        ladd(i)
        x+y+z

    callme()

run.py

from test import add, X, Y, Z

def callme():
  for i in range(100000000):
    add(i)
    X+Y+Z

callme()

লিনাক্সের সময় একটি সামান্য লাভ দেখায়

/usr/bin/time -f "\t%E real,\t%U user,\t%S sys" python run.py 
    0:17.80 real,   17.77 user, 0.01 sys
/tmp/test$ /usr/bin/time -f "\t%E real,\t%U user,\t%S sys" python runlocal.py 
    0:14.23 real,   14.22 user, 0.01 sys

আসল দেয়াল ঘড়ি। ব্যবহারকারী প্রোগ্রামে সময়। সিস্টেমে কল করার জন্য সময় আসে।

https://docs.python.org/3.5/reference/executionmodel.html#resolution-of-names


1

সুপাঠ্যতা

স্টার্টআপ পারফরম্যান্সের পাশাপাশি স্থানীয় importবিবৃতি দেওয়ার জন্য একটি পঠনযোগ্যতার যুক্তিও রয়েছে argument উদাহরণস্বরূপ আমার বর্তমান অজগর প্রকল্পে 1283 এর মধ্য দিয়ে 1283 টি পাইথন লাইন নম্বরটি নিন:

listdata.append(['tk font version', font_version])
listdata.append(['Gtk version', str(Gtk.get_major_version())+"."+
                 str(Gtk.get_minor_version())+"."+
                 str(Gtk.get_micro_version())])

import xml.etree.ElementTree as ET

xmltree = ET.parse('/usr/share/gnome/gnome-version.xml')
xmlroot = xmltree.getroot()
result = []
for child in xmlroot:
    result.append(child.text)
listdata.append(['Gnome version', result[0]+"."+result[1]+"."+
                 result[2]+" "+result[3]])

যদি importবিবৃতি ফাইল উপরের ছিল আমি একটি দীর্ঘ পথ, বা প্রেস উপরে স্ক্রল করতে হবে Home, খুঁজে বের করতে কি ETছিল। তারপরে কোডটি পড়া চালিয়ে যাওয়ার জন্য আমাকে 1283 লাইনে ফিরে যেতে হবে ate

প্রকৃতপক্ষে এমনকি যদি importবিবৃতিটি ফাংশনের শীর্ষে ছিল (বা শ্রেণি) যতগুলি এটি স্থাপন করবে, পেজিং আপ এবং ব্যাক ডাউন প্রয়োজন হবে।

জিনোম সংস্করণ নম্বর প্রদর্শন করা খুব কমই করা হবে তাই importফাইলের শীর্ষে অপ্রয়োজনীয় স্টার্টআপ ল্যাগের পরিচয় দেয়।


0

আমি আমার একটি ইউজকেস উল্লেখ করতে চাই, @ জন মিলিকিন এবং @ ভি কে এর সাথে উল্লিখিত অনুরূপ:

.চ্ছিক আমদানি

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

এইভাবে, আমি আমদানির জন্য অপেক্ষা না করে বা ব্যর্থ হয়ে যাওয়ার পরে বাকী ঘরগুলি পুনরায় শুরু না করেই "পুনরায় আরম্ভ এবং সমস্ত রান" করতে পারি।


0

এটি একটি আকর্ষণীয় আলোচনা। অন্যান্য অনেকের মতো আমি এমনকি এই বিষয়টি কখনও বিবেচনা করি নি। আমার কোনও লাইব্রেরিতে জ্যাঙ্গো ওআরএম ব্যবহার করতে ইচ্ছুক হওয়ার কারণে আমি ফাংশনগুলিতে আমদানি করানোর বিষয়ে কোণঠাসা হয়ে পড়েছি। আমাকে ফোন করতে হচ্ছেdjango.setup()আমার মডেল ক্লাসগুলি আমদানির আগে আমাকে করতে হয়েছিল এবং আইওসি ইনজেক্টর নির্মাণের কারণে এটি ফাইলের শীর্ষে ছিল এটি সম্পূর্ণরূপে নন-জাঙ্গো লাইব্রেরি কোডে টেনে আনা হচ্ছে।

আমি কিছুটা প্রায় হ্যাক করেছি এবং শেষ করে দিয়েছি django.setup() প্রতিটি ক্লাস পদ্ধতির শীর্ষে সিঙ্গলটন কনস্ট্রাক্টর এবং প্রাসঙ্গিক আমদানিটি । এখন এটি দুর্দান্তভাবে কাজ করেছে তবে আমাকে অস্বস্তি করেছে কারণ আমদানি শীর্ষে ছিল না এবং আমদানিগুলির অতিরিক্ত সময় হিট নিয়ে আমিও উদ্বেগ শুরু করেছিলাম। তারপরে আমি এখানে এসে সবার আগ্রহ নিয়ে আগ্রহ নিয়ে পড়লাম।

আমার একটি দীর্ঘ সি ++ ব্যাকগ্রাউন্ড রয়েছে এবং এখন পাইথন / সিথন ব্যবহার করি। আমার এই বিষয়টি হ'ল এটি কেন আপনার আমদানিকৃত বাধা সৃষ্টি না করে আমদানিগুলি ফাংশনে রাখবেন না। এটি ভেরিয়েবলগুলির প্রয়োজন হওয়ার ঠিক আগে স্থান ঘোষণার মতো। সমস্যাটি হচ্ছে আমার কাছে হাজার হাজার লাইন কোড রয়েছে সমস্ত আমদানির উপরে রয়েছে! সুতরাং আমি মনে করি আমি এখন থেকে এটি করব এবং আমি যখন ওখান দিয়ে যাচ্ছি এবং সময় পাব তখন এখানে এবং সেখানে বিজোড় ফাইলটি পরিবর্তন করব।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.