'আমদানি মডিউল' বনাম 'মডিউল আমদানি ফাংশন থেকে'


143

আমি সবসময় এই পদ্ধতি ব্যবহার করে আসছি:

from sys import argv

এবং argvস্রেফ আরজিভি দিয়ে ব্যবহার করুন । তবে এটি ব্যবহারের একটি সম্মেলন রয়েছে:

import sys

এবং দ্বারা আরজিভি ব্যবহার করে sys.argv

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

আমার প্রশ্ন তাই হয়। প্রথম পদ্ধতিটি কি আসলেই স্ক্রিপ্টটি দ্রুত করে তোলে? কোন পদ্ধতিটি সবচেয়ে বেশি পছন্দ করা হয়? কেন?



উত্তর:


175

আমদানি হচ্ছে মডিউল নষ্ট করেন না কিছু ; মডিউলটি সর্বদা সম্পূর্ণভাবে আমদানি করা হয় ( sys.modulesম্যাপিংয়ে), সুতরাং আপনি ব্যবহার করেন import sysবা from sys import argvকোনও প্রতিকূলতা তৈরি করেন না।

দুটি বিবৃতি মধ্যে পার্থক্য শুধুমাত্র নাম আবদ্ধ হয়; import sysনামটিকে sysমডিউলটিতে (তাই sys-> sys.modules['sys']) from sys import argvআবদ্ধ করুন , যখন একটি পৃথক নামের সাথে আবদ্ধ করুন argv, মডিউলটির ভিতরে থাকা বৈশিষ্ট্যটি সরাসরি নির্দেশ করে (তাই argv-> sys.modules['sys'].argv)। sysমডিউলটির বাকি অংশ এখনও রয়েছে, আপনি মডিউলটি থেকে অন্য কিছু ব্যবহার করেন বা না করেন।

দুটি পদ্ধতির মধ্যে কোনও পারফরম্যান্সের পার্থক্য নেই। হ্যাঁ, sys.argvদুটি জিনিস সন্ধান করতে হবে; এটি sysআপনার গ্লোবাল নেমস্পেসে সন্ধান করতে হবে (মডিউলটি সন্ধান করে), তারপরে বৈশিষ্ট্যটি অনুসন্ধান করবে argv। এবং হ্যাঁ, ব্যবহার করে from sys import argvআপনি গুণাবলীর খোঁজ এড়িয়ে যেতে পারেন, যেহেতু আপনার কাছে ইতিমধ্যে বৈশিষ্ট্যের প্রত্যক্ষ রেফারেন্স রয়েছে। তবে importবিবৃতিটিতে এখনও সেই কাজটি করতে হবে, আমদানির সময় এটি একই বৈশিষ্ট্যটি দেখায় এবং আপনাকে কেবল argv একবার ব্যবহার করতে হবে । যদি আপনাকে argvএকটি লুপে কয়েক হাজার বার ব্যবহার করতে হয় তবে এটি সম্ভবত একটি পার্থক্য তৈরি করতে পারে, তবে এই নির্দিষ্ট ক্ষেত্রে এটি সত্যিই তা করে না।

এক বা অন্যটির মধ্যে তার পরে পছন্দ কোডিং শৈলীর পরিবর্তে হওয়া উচিত ।

একটি বড় মডিউলে, আমি অবশ্যই ব্যবহার করব import sys; কোড ডকুমেন্টেশনের বিষয়টি গুরুত্বপূর্ণ, এবং sys.argvকোনও বৃহত মডিউলটিতে কোথাও ব্যবহার করা আপনি যেটি উল্লেখ করছেন তা তার চেয়ে আরও পরিষ্কার করে argvদেয়।

আপনি যদি কেবলমাত্র কোনও জায়গাটি কোনও ফাংশন কল করার জন্য argvকোনও '__main__'ব্লকের মধ্যে main()রাখেন, from sys import argvযদি আপনি সে সম্পর্কে আরও খুশি হন তবে যে কোনও উপায়ে ব্যবহার করুন :

if __name__ == '__main__':
    from sys import argv
    main(argv)

আমি এখনও import sysসেখানে নিজেকে ব্যবহার করব। সমস্ত জিনিস সমান (এবং এগুলি হ'ল পারফরম্যান্স এবং এটি লেখার জন্য ব্যবহৃত অক্ষরের সংখ্যা অনুসারে), এটি আমার পক্ষে চোখের উপর সহজ just

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

 import somemodule

 def somefunction():
      localname = somemodule.somefunctionorother
      while test:
          # huge, critical loop
          foo = localname(bar)

1
আপনার এমন প্যাকেজ রয়েছে যা সাবপ্যাকেজগুলি বা মডিউলগুলির সাথে প্যাকেজ রয়েছে যা শীর্ষ স্তরের প্যাকেজের sub সাব-প্যাকেজগুলি / মডিউলগুলির একটির বৈশিষ্ট্য প্রকাশ করে। ব্যবহারের পরিবর্তে from...importআপনি এটি করতে পারবেন যা প্যাকেজের মধ্যে যৌক্তিক বা ধারণাগত গ্রুপিং থাকলেও আপনার প্যাকেজের ব্যবহারকারীদের জন্য জিনিসগুলিকে কিছুটা সুবিধাজনক করে তুলতে চাইলে এটি কার্যকর হতে পারে। ( ভালো কিছু করে, আমি বিশ্বাস করি।)package.attributepackage.subpackage_or_module.attributenumpy
Jab

জ্যাঙ্গোতে আপনার অনেকগুলি স্পট রয়েছে যেখানে পছন্দ মতো জিনিসগুলি from django.core.management.base import BaseCommandআরও ভাল এবং অন্য যে কোনও কিছু (বিশেষত import django) অপঠনযোগ্য কোডের দিকে নিয়ে যায়। সুতরাং আমি যখন এই উত্তরটি পছন্দ করি তখন আমার মনে হয় কিছু গ্রন্থাগার রয়েছে (এবং বিশেষত কিছু ফ্রেমওয়ার্ক) যেখানে কনভেনশনটি খালি আমদানি লঙ্ঘন করবে। সর্বদা হিসাবে, একটি প্রদত্ত পরিস্থিতিতে সবচেয়ে ভাল কি সম্পর্কে আপনার রায় ব্যবহার করুন। তবে স্পষ্টতই ভুল (অন্য কথায় আমি বেশিরভাগ অংশে সম্মত)।
নিউরোনেট

1
@JAB: আপনি এখনও ব্যবহার করতে পারেন import ... asএকটি ভিন্ন নাম প্যাকেজ দেখুন: import package.subpackage_or_module as shortnamefrom parent import subমূলত একই জিনিসটি করে।
মার্টিজন পিটারস

43

import moduleপরিবর্তে ব্যবহারের পক্ষে দুটি কারণ রয়েছে from module import function

প্রথম নামস্থান। বিশ্বব্যাপী নেমস্পেসে কোনও ফাংশন আমদানি করা নাম সংঘর্ষের ঝুঁকি নিয়ে।

দ্বিতীয়টি প্রমিত মডিউলগুলির সাথে প্রাসঙ্গিক নয়, তবে আপনার জন্য বিশেষত বিকাশের সময় মডিউলগুলির নিজস্ব significant এটি reload()একটি মডিউল বিকল্প । এই বিবেচনা:

from module import func
...
reload(module)
# func still points to the old code

অন্য দিকে

import module
...
reload(module)
# module.func points to the new code

গতি হিসাবে ...

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

আপনি মডিউলটি আমদানি করুন বা মডিউল থেকে কোনও ফাংশন আমদানি করুন, পাইথন পুরো মডিউলটিকে পার্স করবে। মডিউলটি যেভাবেই আমদানি করা হয়। "একটি ফাংশন আমদানি করা" ফাংশনটিকে নামের সাথে আবদ্ধ করা ছাড়া আর কিছুই নয়। আসলে import moduleদোভাষীর চেয়ে কম কাজ from module import func


6
রিলোড () পাইথন 2-এ একটি বিল্টিন ছিল; পাইথন ৩
আন্দ্রে

আমি ভেবেছিলাম বৃত্তাকার আমদানি নির্ভরতাগুলির সাথেও এর অন্তর্ভুক্তি রয়েছে?
এডিপি

18

আমি from importযখনই এটি পঠনযোগ্যতার উন্নতি করি তখন আমি ব্যবহার করি । উদাহরণস্বরূপ, আমি পছন্দ করি (সেমিকোলনগুলি কেবল এখানে স্থান বাঁচাতে হয়):

from collections import defaultdict
from foomodule import FooBar, FooBaz
from twisted.internet.protocol import Factory
defaultdict(); FooBar(); FooBaz(); Factory()

পরিবর্তে:

import collections
import foomodule
import twisted.internet.protocol
collections.defaultdict(); foomodule.FooBar(); foomodule.FooBaz()
twisted.internet.protocol.Factory()

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

আমি importযদি মডিউল থেকে প্রচুর সংক্ষিপ্ত নাম ব্যবহার করি তবে আমি নিয়মিত পছন্দ করি :

import sys
sys.argv; sys.stderr; sys.exit()

বা যদি কোনও নামটি এত জেনেরিক হয় যে এর নামস্থানটির বাইরে এটি বোঝা যায় না:

import json
json.loads(foo)

from json import loads
loads(foo)  # potentially confusing

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

18

আমার মতে নিয়মিত ব্যবহারযোগ্যতা importপঠনযোগ্যতা উন্নত করে। পাইথন কোড পর্যালোচনা করার সময় আমি দেখতে চাই যে প্রদত্ত ফাংশন বা শ্রেণিটি যেখানে ব্যবহৃত হয়েছে সেখান থেকে আসে। তথ্যটি পেতে এটি আমাকে মডিউলটির শীর্ষে স্ক্রোল করা থেকে বাঁচায়।

দীর্ঘ মডিউল নামগুলির জন্য আমি কেবল asকীওয়ার্ডটি ব্যবহার করি এবং তাদের সংক্ষিপ্ত নামগুলি দিয়ে থাকি :

import collections as col
import foomodule as foo
import twisted.internet.protocol as twip

my_dict = col.defaultdict()
foo.FooBar()
twip_fac = twip.Factory()

ব্যতিক্রম হিসাবে আমি মডিউলটি from module import somethingমোকাবেলা করার সময় সর্বদা স্বরলিপি ব্যবহার করি __future__। আপনি পাইথন 2 এ ডিফল্টরূপে সমস্ত স্ট্রিংগুলি ইউনিকোড হতে চাইলে আপনি এটি আর কোনও উপায়ে করতে পারবেন না, যেমন

from __future__ import unicode_literals
from __future__ import print_function

আমেন! "আমদানি হিসাবে" একটি বিজয়ী সমন্বয় :-)
paj28

4

যদিও import sysএবং from sys import agrvউভয়ই পুরো sysমডিউলটি আমদানি করে , পরবর্তীকৃত নাম বাঁধার ব্যবহার করে তাই কেবলমাত্র argvমডিউলটি বাকী কোডটিতে অ্যাক্সেসযোগ্য।

কিছু লোকের পক্ষে এটি পছন্দসই স্টাইল হবে কারণ এটি কেবলমাত্র আপনার স্পষ্টভাবে বিবৃত ফাংশনটি অ্যাক্সেসযোগ্য করে তোলে।

এটি তবে সম্ভাব্য নাম সংঘাতের পরিচয় দেয়। আপনার যদি অন্য একটি মডিউল নামকরণ করা থাকে argv? নোট আপনি স্পষ্টভাবে ফাংশনটি আমদানি করতে পারেন এবং এর সাথে নাম পরিবর্তন করতে পারেন from sys import argv as sys_argv, একটি কনভেনশন যা সুস্পষ্ট আমদানির সাথে মিলিত হয় এবং নাম স্থান সংঘাতের সম্ভাবনা কম দেয়।


2
তাহলে এর if sys_argv:চেয়ে ভাল আর কীভাবে if sys.argv:? আমি জানি দ্বিতীয় বিবৃতিটির অর্থ কী, আমি উদ্ভট আমদানিতে ব্যাকট্রাক না করে প্রথম ফর্মটির অর্থ কী তা আমার কোনও ধারণা নেই।
এমএসডব্লিউ

1

আমি সম্প্রতি আমার কাছে এই প্রশ্নটি জিজ্ঞাসা করেছি। আমি বিভিন্ন পদ্ধতি সময়সই।

অনুরোধ লাইব্রেরি

def r():
    import requests
    return 'hello'
timeit r() # output: 1000000 loops, best of 3: 1.55 µs per loop

def rg():
    from requests import get
    return 'hello'
timeit rg() # output: 100000 loops, best of 3: 2.53 µs per loop

সুন্দরী স্যুপ লাইব্রেরি

def bs():
    import bs4
    return 'hello' 
timeit bs() # output: 1000000 loops, best of 3: 1.53 µs per loop

def be():
    from bs4 import BeautifulSoup
    return 'hello'
timeit be() # output: 100000 loops, best of 3: 2.59 µs per loop

json গ্রন্থাগার

def js():
    import json
    return 'hello'
timeit js() # output: 1000000 loops, best of 3: 1.53 µs per loop

def jl():
    from json import loads
    return 'hello'
timeit jl() # output: 100000 loops, best of 3: 2.56 µs per loop

sys গ্রন্থাগার

def s():
    import sys
    return 'hello'
timeit s() # output: 1000000 loops, best of 3: 1.55 µs per loop

def ar():
    from sys import argv
    return 'hello'
timeit ar() # output: 100000 loops, best of 3: 2.87 µs per loop

এটা আমার মনে হচ্ছে যে নেই কর্মক্ষমতা সামান্য পার্থক্য।


আপনি একটি বৈশিষ্ট্য অনুসন্ধানে যুক্ত করছেন। তুলনা করতে import moduleসঙ্গে from module import nameসঠিকভাবে যোগ করার যে নাম লুকআপ import moduleকেস। উদাহরণস্বরূপ sys.argv, arপরীক্ষায় লাইন যুক্ত করুন , তবুও একটি পার্থক্য থাকবে, কারণ করা কাজটি কিছুটা ভিন্ন, কারণ বিভিন্ন বাইটকোড উত্পন্ন হয় এবং বিভিন্ন কোডেপথ সম্পাদিত হয়।
মার্টিজন পিটারস

2
নোট করুন যে আমি সরাসরি আমার উত্তরে সেই পার্থক্যটি সম্বোধন করেছি; সেখানে ব্যবহার মধ্যে একটি পার্থক্য হতে হবে import sysতারপর ব্যবহার sys.argvএকটি লুপ সময় হাজার হাজার বনাম from sys import argvতারপর ব্যবহার argv। কিন্তু আপনি না। আপনার মডিউলের গ্লোবাল স্তরে আপনি একবারে যে কাজগুলি করেন তার জন্য আপনার সময়সীমার মধ্যে অণুবীক্ষণিক পার্থক্য নয়, পাঠযোগ্যতার জন্য সত্যই অনুকূলিত হওয়া উচিত।
মার্টিজন পিটারস

1
Ahhhh! এবং আমি ভেবেছিলাম আমি কিছু ছিলাম! :) আমি কেবল আপনার উত্তর স্কিম করেছিলাম। দেখে মনে হচ্ছে আমি সেটার উপরে বন্দুকটি ঝাঁপিয়েছি। বিনীত হতে ভাল লাগছে।
tmthyjames

-1

প্রকাশিত কোডের টুকরোগুলি দেখে, পুরো মডিউলগুলি আমদানি করা এবং module.functionকমপক্ষে মানক মডিউলগুলির জন্য উল্লেখ করা বেশ মানক। এক ব্যতিক্রম বলে মনে হচ্ছেdatetime

from datetime import datetime, timedelta

সুতরাং আপনি datetime.now()চেয়ে বরং বলতে পারেন datetime.datetime.now()

আপনি যদি কর্মক্ষমতা সম্পর্কে উদ্বিগ্ন হন তবে আপনি সর্বদা বলতে পারেন (উদাহরণস্বরূপ)

argv = sys.argv

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


-2

আমি কেবল এটি যুক্ত করতে চাই যদি আপনি এর মতো কিছু করেন

from math import sin

(বা অন্য কোনও অন্তর্নির্মিত লাইব্রেরি sysবা এর মতো posix), তারপরে sinআপনার মডিউলটির জন্য ডকুমেন্টেশনে অন্তর্ভুক্ত করা হবে (যেমন আপনি কখন করবেন >>> help(mymodule)বা এটি $ pydoc3 mymoduleএড়াতে: ব্যবহার করে আমদানি করুন:

import math
from math import sin as _sin

পিএস: একটি অন্তর্নির্মিত লাইব্রেরি হ'ল সি কোড থেকে সংকলিত এবং পাইথনের সাথে অন্তর্ভুক্ত। argparse, osএবং ioঅন্তর্নির্মিত প্যাকেজগুলি নয়

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