'आयात मॉड्यूल' या 'मॉड्यूल आयात से' का उपयोग करें?


410

मैंने एक व्यापक मार्गदर्शिका खोजने की कोशिश की है कि क्या इसका उपयोग करना सबसे अच्छा है import moduleया from module import? मैंने अभी पाइथन के साथ शुरुआत की है और मैं सर्वश्रेष्ठ अभ्यासों को ध्यान में रखकर शुरू करने की कोशिश कर रहा हूं।

मूल रूप से, मैं उम्मीद कर रहा था कि अगर कोई भी अपने अनुभव साझा कर सकता है, तो अन्य डेवलपर्स की क्या प्राथमिकताएं हैं और सड़क के नीचे किसी भी गोच से बचने का सबसे अच्छा तरीका क्या है ?


5
मैं आपको केवल यह बताना चाहता हूं, कि चयनित उत्तर गलत है। यह बताता है कि अंतर व्यक्तिपरक है जबकि अंतर है। यह संभवतः कीड़े का पता लगाने के लिए कठिन हो सकता है। देखें माइकल रे लव्ट्स का जवाब।
Mayou36


2
विशिष्ट नामित पहचानकर्ता 'from module import X,Y,Zबनाम आयात करने के बीच अंतर का एक नरक है'from module import * । उत्तरार्द्ध आपके नाम स्थान को प्रदूषित करता है और मॉड्यूल में क्या चल रहा है इसके आधार पर अप्रत्याशित परिणाम दे सकता है। इससे भी बदतर from module import *कई मॉड्यूल के साथ कर रहा है ।
smci

जवाबों:


474

के बीच का अंतर import moduleऔर from module import fooमुख्य रूप से व्यक्तिपरक है। आपको जो सबसे अच्छा लगता है उसे चुनें और उसके उपयोग में लगातार रहें। यहाँ कुछ बिंदु हैं जो आपको तय करने में मदद करेंगे।

import module

  • पेशेवरों:
    • अपने importबयानों का कम रखरखाव । मॉड्यूल से किसी अन्य आइटम का उपयोग शुरू करने के लिए किसी भी अतिरिक्त आयात को जोड़ने की आवश्यकता नहीं है
  • विपक्ष:
    • module.fooआपके कोड में टाइपिंग थकाऊ और निरर्थक हो सकती है ( import module as moटाइपिंग के बाद टेडियम को कम से कम किया जा सकता है mo.foo)

from module import foo

  • पेशेवरों:
    • उपयोग करने के लिए कम टाइपिंग foo
    • मॉड्यूल के किन मदों पर अधिक नियंत्रण प्राप्त किया जा सकता है
  • विपक्ष:
    • मॉड्यूल से एक नए आइटम का उपयोग करने के लिए आपको अपना importस्टेटमेंट अपडेट करना होगा
    • आप संदर्भ खो देते हैं foo। उदाहरण के लिए, इसकी ceil()तुलना में कम स्पष्ट हैmath.ceil()

या तो विधि स्वीकार्य है, लेकिन उपयोग करें from module import *

कोड के किसी भी उचित बड़े सेट के लिए, यदि आप import *संभवतः इसे मॉड्यूल में सीमेंट कर रहे हैं, तो हटाया नहीं जा सकता। ऐसा इसलिए है क्योंकि यह निर्धारित करना मुश्किल है कि कोड में उपयोग की जाने वाली कौन सी वस्तुएं 'मॉड्यूल' से आ रही हैं, जिससे उस बिंदु पर पहुंचना आसान हो जाता है, जहां आपको लगता है कि आप importकिसी और का उपयोग नहीं करते हैं, लेकिन यह सुनिश्चित करना बेहद मुश्किल है।


66
+1 "मॉड्यूल इंपोर्ट से *" के उपयोग को हतोत्साहित करने के लिए, यह सिर्फ नेमस्पेस क्लैट करता है।
क्रिश्चियन विट्स

22
नाम स्थान को अव्यवस्थित करना "आयात *" का सबसे समस्याग्रस्त हिस्सा नहीं है, यह पठनीयता में कमी है: किसी भी नाम का टकराव खुद को (इकाई) परीक्षण में दिखाएगा। लेकिन आयात किए गए मॉड्यूल से आपके द्वारा उपयोग किए जाने वाले सभी नाम नंगे होंगे, नारी के संकेत के साथ कि वे कहां से आए थे। मैं "आयात *" पूरी तरह से घृणा करता हूं।
जुरगेन ए। इरहार्ड

21
क्या पायथन का ज़ेन स्पष्ट नहीं है कि निहित से बेहतर है?
एंटनी कोच

8
from module import *विशेष रूप से उपयोगी हो सकता है, अगर इसका उपयोग कर रहे हैं if(windows):\n\t from module_win import * \n else: \n\t from module_lin import *:। तब आपके मूल मॉड्यूल में संभवतः OS स्वतंत्र फ़ंक्शन नाम शामिल हो सकते हैं, यदि फ़ंक्शन नाम मॉड्यूल_lin & मॉड्यूल_win में समान नाम हैं। यह सशर्त रूप से या तो वर्ग को विरासत में मिला है।
ऐशसेन

19
@anishsane। इसका एक और तरीका है। आयात मॉड्यूल_विन कुछ के रूप में। फिर हमेशा कुछ
विनय

163

यहां एक और विवरण है, जिसका उल्लेख नहीं है, एक मॉड्यूल से संबंधित है। दी यह बहुत आम नहीं हो सकता है, लेकिन मैं समय-समय पर इसकी जरूरत है।

पायथन में जिस तरह से संदर्भ और नाम बंधन काम करता है, उसके कारण, यदि आप किसी मॉड्यूल में कुछ प्रतीक को अपडेट करना चाहते हैं, तो उस मॉड्यूल के बाहर से, foo.bar, और अन्य आयात कोड "परिवर्तन" देखें, जो आपको बदलना है, आपको फू आयात करना होगा निश्चित तरीका। उदाहरण के लिए:

मॉड्यूल फू:

bar = "apples"

मॉड्यूल a:

import foo
foo.bar = "oranges"   # update bar inside foo module object

मॉड्यूल बी:

import foo           
print foo.bar        # if executed after a's "foo.bar" assignment, will print "oranges"

हालाँकि, यदि आप मॉड्यूल नामों के बजाय प्रतीक नामों को आयात करते हैं, तो यह काम नहीं करेगा।

उदाहरण के लिए, अगर मैं मॉड्यूल में ऐसा करता हूं:

from foo import bar
bar = "oranges"

किसी भी कोड से बाहर के कोड को "संतरे" के रूप में नहीं देखा जाएगा क्योंकि बार की मेरी सेटिंग ने मॉड्यूल के अंदर "बार" नाम को प्रभावित किया है, यह "फू मॉड्यूल ऑब्जेक्ट" में नहीं पहुंचा और इसके "बार" को अपडेट नहीं किया।


उस अंतिम उदाहरण के साथ, क्या आप अभी भी 'फू' के अंदर 'बार' को अपडेट करने के लिए 'foo.bar = "ऑरेंज" कह सकते हैं?
velocirabbit

4
नहीं, अंतिम उदाहरण में, 'फू' नाम अज्ञात है
घिसलेन लेवेके

31
इस सवाल पर "सही" उत्तर प्रदान करता है: दो आयात वेरिएंट में क्या अंतर है
Mayou36

3
इस उत्तर को सही साबित करने के लिए कुछ स्निपेट लिखा, लेकिन इसके पीछे तर्क क्या है?
हुंगबेइदु

मुझे लगता है कि आप जो कह रहे हैं वह स्थानीय चरों के लिए आयात नाम है लेकिन वैश्विक चरों के लिए मॉड्यूल नाम आयात करना है ???
विनयुनुच्स

79

हालांकि कई लोग पहले से ही importबनाम के बारे में import fromसमझाते हैं, मैं हुड के नीचे क्या होता है, और जहां सभी जगह बदलती हैं, उसके बारे में थोड़ा और समझाने की कोशिश करना चाहता हूं।


import foo:

आयात करता है foo, और वर्तमान नामस्थान में उस मॉड्यूल का संदर्भ बनाता है। फिर आपको मॉड्यूल के अंदर से किसी विशेष विशेषता या विधि तक पहुंचने के लिए पूर्ण मॉड्यूल पथ को परिभाषित करने की आवश्यकता है।

जैसे foo.barलेकिन नहींbar

from foo import bar:

आयात foo, और बनाता संदर्भ सूचीबद्ध सभी सदस्यों के लिए ( bar)। चर सेट नहीं करता है foo

जैसे barलेकिन नहीं bazयाfoo.baz

from foo import *:

आयात करता है foo, और वर्तमान नाम स्थान में उस मॉड्यूल द्वारा परिभाषित सभी सार्वजनिक वस्तुओं के संदर्भ बनाता है ( __all__यदि __all__मौजूद सब कुछ सूचीबद्ध है, अन्यथा सब कुछ जो इसके साथ शुरू नहीं होता है _)। चर सेट नहीं करता है foo

जैसे barऔर bazलेकिन _quxया नहीं foo._qux


अब देखते हैं कि हम कब क्या करते हैं import X.Y:

>>> import sys
>>> import os.path

sys.modulesनाम के साथ जांचें osऔर os.path:

>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>

के साथ चेक globals()और locals()नेमस्पेस dicts osऔर os.path:

 >>> globals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> locals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> globals()['os.path']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'os.path'
>>>

उपरोक्त उदाहरण से हमने पाया कि केवल osस्थानीय और वैश्विक नामस्थान में डाला गया है। तो, हम उपयोग करने में सक्षम होना चाहिए:

 >>> os
 <module 'os' from
  '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
 >>> os.path
 <module 'posixpath' from
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
 >>>

लेकिन नहीं path

>>> path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined
>>>

एक बार जब आप हटाना osस्थानीय लोगों से () नाम स्थान, तुम नहीं एक्सेस कर पाएंगे हो जाएगा osऔर साथ ही os.path, भले ही वे sys.modules में मौजूद है:

>>> del locals()['os']
>>> os
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>> os.path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>

अब बात करते हैं import from:

from:

>>> import sys
>>> from os import path

के sys.modulesसाथ की जाँच करें osऔर os.path:

>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>

हमने पाया कि sys.modulesहमने उपयोग करने से पहले जैसा पाया था, वैसा ही पायाimport name

ठीक है, आइए देखें कि यह कैसा दिख रहा है locals()और globals()नाम स्थान के डिकेट:

>>> globals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> locals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['os']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'os'
>>>

आप द्वारा pathनहीं नाम का उपयोग करके उपयोग कर सकते हैं os.path:

>>> path
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> os.path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>

चलिए 'पथ' को हटाते हैं locals():

>>> del locals()['path']
>>> path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined
>>>

एक उपनाम का उपयोग करके एक अंतिम उदाहरण:

>>> from os import path as HELL_BOY
>>> locals()['HELL_BOY']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['HELL_BOY']
<module 'posixpath' from /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>>

और कोई रास्ता नहीं परिभाषित:

>>> globals()['path']
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
KeyError: 'path'
>>>

8
जबकि यह क्रिया है, यह वास्तव में एक काफी जटिल प्रश्न के लिए सूची में सबसे अच्छा जवाब है। यह "हुड के तहत" सूक्ष्मताओं को समझाने में मदद करने के लिए वास्तविक कोड प्रदान करता है, जो इस विशेष मुद्दे के लिए शैली से अधिक महत्वपूर्ण हैं। काश मैं इसे एक से अधिक बार उखाड़ सकता!
माइक विलियमसन

क्या as SYMBOLपरिवर्तन का उपयोग करने से यह उत्तर बिल्कुल काम करता है?
मैक्सिमिलियन बर्स्ज़ले

40

दोनों तरीकों को एक कारण के लिए समर्थन किया जाता है: ऐसे समय होते हैं जब कोई दूसरे की तुलना में अधिक उपयुक्त होता है।

  • import module: अच्छा है जब आप मॉड्यूल से कई बिट्स का उपयोग कर रहे हैं। दोष यह है कि आपको मॉड्यूल नाम के साथ प्रत्येक संदर्भ को अर्हता प्राप्त करने की आवश्यकता होगी।

  • from module import ...: अच्छा है कि आयातित आइटम सीधे मॉड्यूल नाम उपसर्ग के बिना उपयोग करने योग्य हैं। दोष यह है कि आपको प्रत्येक उपयोग की जाने वाली चीज़ को सूचीबद्ध करना होगा, और यह कोड में स्पष्ट नहीं है कि कुछ कहाँ से आया है।

कौन सा उपयोग करना है यह निर्भर करता है कि कोड स्पष्ट और पठनीय बनाता है, और व्यक्तिगत प्राथमिकता के साथ करने के लिए थोड़ा अधिक है। मैं import moduleआम तौर पर इस ओर झुकता हूं क्योंकि कोड में यह बहुत स्पष्ट है कि कोई ऑब्जेक्ट या फ़ंक्शन कहां से आया है। मैं का उपयोग करें from module import ...जब मैं किसी वस्तु का उपयोग कर रहा / एक से कार्य बहुत कोड में।


1
क्या उपयोग करने का कोई तरीका है from M import Xऔर अभी भी किसी तरह क्वालिफायर का उपयोग करने का लाभ मिलता है? ऐसा लगता है कि आप दोनों दुनिया के सर्वश्रेष्ठ प्राप्त कर सकते हैं यदि आप M.Xउस आयात के बाद भी कर सकते हैं।
आर्थ्रोपॉड

@ कार्टग्राफोड: किंडा। आप कर सकते हैं class m: from something.too.long import x, y, z। वास्तव में हालांकि यह अनुशंसा नहीं करेंगे।
रेयान

35

मैं व्यक्तिगत रूप से हमेशा उपयोग करता हूं

from package.subpackage.subsubpackage import module

और फिर सब कुछ के रूप में उपयोग

module.function
module.modulevar

आदि कारण यह है कि एक ही समय में आपके पास कम आह्वान है, और आप स्पष्ट रूप से प्रत्येक दिनचर्या के मॉड्यूल नामस्थान को परिभाषित करते हैं, कुछ ऐसा जो बहुत उपयोगी है यदि आपको अपने स्रोत में दिए गए मॉड्यूल के उपयोग की खोज करनी है।

यह कहने की आवश्यकता नहीं है कि आयात * का उपयोग न करें, क्योंकि यह आपके नाम स्थान को प्रदूषित करता है और यह आपको यह नहीं बताता है कि दिया गया फ़ंक्शन कहां से (किस मॉड्यूल से)

बेशक, आप मुसीबत में भाग सकते हैं यदि आपके पास दो अलग-अलग पैकेजों में दो अलग-अलग मॉड्यूल के लिए एक ही मॉड्यूल का नाम है, जैसे

from package1.subpackage import module
from package2.subpackage import module

इस मामले में, बेशक आप मुसीबतों में भाग रहे हैं, लेकिन फिर एक मजबूत संकेत है कि आपका पैकेज लेआउट त्रुटिपूर्ण है, और आपको इसे पुनर्विचार करना होगा।


10
अंतिम स्थिति में, आप हमेशा उपयोग कर सकते हैं: आयात pkgN.sub.module modN के रूप में आप प्रत्येक मॉड्यूल के लिए अलग नाम दे रहे हैं। आप एक लंबे नाम को छोटा करने के लिए या एक ही नाम परिवर्तन के साथ एक ही एपीआई (जैसे DB एपीआई मॉड्यूल) के कार्यान्वयन के बीच स्विच करने के लिए 'आयात modulename as mod1' पैटर्न का उपयोग कर सकते हैं।
जेफ शैनन

15
import module

सबसे अच्छा है जब आप मॉड्यूल से कई कार्यों का उपयोग करेंगे।

from module import function

सबसे अच्छा है जब आप एक मॉड्यूल से सभी कार्यों और प्रकारों के साथ वैश्विक नाम स्थान को प्रदूषित करने से बचना चाहते हैं जब आपको केवल आवश्यकता होती है function


7
वैश्विक नामस्थान में निश्चित रूप से केवल एक चीज है अगर आप 'आयात मॉड्यूल' 'मॉड्यूल' करते हैं? यदि आप 'से .. आयात *' करते हैं तो आप केवल नाम स्थान को प्रदूषित करते हैं।
जॉन फोउहि

10

मैंने इन दोनों विधियों के बीच एक और सूक्ष्म अंतर खोजा है।

यदि मॉड्यूल fooनिम्नलिखित आयात का उपयोग करता है:

from itertools import count

तब मॉड्यूल barगलती से उपयोग कर सकता है countजैसे कि यह में परिभाषित किया गया था foo, इसमें नहीं itertools:

import foo
foo.count()

यदि fooउपयोग करता है:

import itertools

गलती अभी भी संभव है, लेकिन कम होने की संभावना है। barकी आवश्यकता है:

import foo
foo.itertools.count()

इससे मुझे कुछ परेशानी हुई। मेरे पास एक मॉड्यूल था जो गलती से एक मॉड्यूल से एक अपवाद का आयात करता था जो इसे परिभाषित नहीं करता था, केवल इसे अन्य मॉड्यूल (उपयोग करके from module import SomeException) से आयात किया था । जब आयात की आवश्यकता नहीं थी और हटा दिया गया था, तो आक्रामक मॉड्यूल टूट गया था।


10

यहाँ एक और अंतर का उल्लेख नहीं है। इसे http://docs.python.org/2/tutorial/modules.html से वर्बेटिम कॉपी किया गया है

उपयोग करते समय ध्यान दें

from package import item

आइटम या तो पैकेज का एक सबमॉड्यूल (या सबपैकेज) हो सकता है, या पैकेज में परिभाषित कोई अन्य नाम, जैसे कोई फ़ंक्शन, वर्ग या चर। आयात विवरण पहले परीक्षण करता है कि आइटम पैकेज में परिभाषित है या नहीं; यदि नहीं, तो यह मानता है कि यह एक मॉड्यूल है और इसे लोड करने का प्रयास करता है। यदि यह इसे खोजने में विफल रहता है, तो एक ImportError अपवाद उठाया जाता है।

इसके विपरीत, जब सिंटैक्स का उपयोग करना पसंद है

import item.subitem.subsubitem

अंतिम को छोड़कर प्रत्येक आइटम एक पैकेज होना चाहिए; अंतिम आइटम एक मॉड्यूल या एक पैकेज हो सकता है लेकिन पिछले आइटम में परिभाषित एक वर्ग या फ़ंक्शन या चर नहीं हो सकता है।


एक और बात मैंने देखा था कि आइटम भी तो पैकेज के अंदर एक submodule काम करता है लेकिन "आयात पैकेज" "पैकेज आयात मद से" है अगर package.item.subitem = ... नहीं एक खाली साथ काम init पैकेज के .py, जब तक कि हम पैकेज की init फ़ाइल में "आयात आइटम" है ।
अमितोज दंडियाना

6

चूंकि मैं भी एक शुरुआती हूं, इसलिए मैं इसे सरल तरीके से समझाने की कोशिश करूंगा: पायथन में, हमारे पास तीन प्रकार के importबयान हैं:

1. सामान्य आयात:

import math

इस प्रकार का आयात मेरा व्यक्तिगत पसंदीदा है, इस आयात तकनीक का एकमात्र नकारात्मक पहलू यह है कि यदि आपको किसी मॉड्यूल के फ़ंक्शन का उपयोग करने की आवश्यकता है, तो आपको निम्नलिखित सिंटैक्स का उपयोग करना होगा:

math.sqrt(4)

बेशक, यह टाइपिंग के प्रयास को बढ़ाता है लेकिन एक शुरुआत के रूप में, यह आपको मॉड्यूल और इसके साथ जुड़े फ़ंक्शन का ट्रैक रखने में मदद करेगा, (एक अच्छा टेक्स्ट एडिटर टाइपिंग प्रयास को काफी कम कर देगा और अनुशंसित है)।

इस आयात विवरण का उपयोग करके टाइपिंग प्रयास को और कम किया जा सकता है:

import math as m

अब, उपयोग करने के बजाय math.sqrt()आप उपयोग कर सकते हैं m.sqrt()

2. समारोह आयात:

from math import sqrt

इस प्रकार का आयात सबसे उपयुक्त है यदि आपके कोड को केवल मॉड्यूल से एकल या कुछ फ़ंक्शन तक पहुंचने की आवश्यकता है, लेकिन मॉड्यूल से किसी भी नए आइटम का उपयोग करने के लिए आपको आयात विवरण अपडेट करना होगा।

3. यूनिवर्सल आयात:

from math import * 

यद्यपि यह टाइपिंग के प्रयास को काफी कम कर देता है, लेकिन इसकी अनुशंसा नहीं की जाती है क्योंकि यह आपके कोड को मॉड्यूल से विभिन्न कार्यों से भर देगा और उनका नाम उपयोगकर्ता-परिभाषित कार्यों के नाम के साथ संघर्ष कर सकता है। उदाहरण:

यदि आपके पास अपने स्वयं के नामित sqrt का फ़ंक्शन है और आप गणित आयात करते हैं, तो आपका फ़ंक्शन सुरक्षित है: आपका sqrt है और math.sqrt है। यदि आप गणित आयात से करते हैं *, हालांकि, आपके पास एक समस्या है: अर्थात्, एक ही नाम के साथ दो अलग-अलग कार्य। स्रोत: कोडेक अकादमी


5
import package
import module

importटोकन के साथ , एक मॉड्यूल होना चाहिए (पायथन कमांड्स वाली फाइल) या एक पैकेज ( sys.pathफाइल में एक फ़ोल्डर __init__.py।)

जब सबपैकेज होते हैं:

import package1.package2.package
import package1.package2.module

फ़ोल्डर (पैकेज) या फ़ाइल (मॉड्यूल) के लिए आवश्यकताओं को एक ही हैं, लेकिन फ़ोल्डर या फ़ाइल होना चाहिए अंदर package2जो अंदर होना चाहिए package1, और दोनों package1और package2शामिल होना चाहिए __init__.pyफ़ाइलें। https://docs.python.org/2/tutorial/modules.html

fromआयात की शैली के साथ :

from package1.package2 import package
from package1.package2 import module

पैकेज या मॉड्यूल के बजाय (या ) के importरूप में बयान के साथ फ़ाइल के नाम स्थान में प्रवेश करती है । आप हमेशा अधिक सुविधाजनक नाम से बंध सकते हैं:modulepackagepackage1.package2.module

a = big_package_name.subpackage.even_longer_subpackage_name.function

केवल fromआयात की शैली आपको किसी विशेष फ़ंक्शन या चर का नाम देने की अनुमति देती है:

from package3.module import some_function

अनुमति है, लेकिन

import package3.module.some_function 

अनुमति नहीं है।


4

लोगों ने जो कुछ भी कहा है, उसे जोड़ने के लिए from x import *: यह बताने में अधिक मुश्किल है कि नाम कहां से आए हैं, यह पाइलिंट जैसे कोड चेकर्स को फेंक देता है। वे उन नामों को अपरिभाषित चर के रूप में रिपोर्ट करेंगे।


3

इसका मेरा खुद का जवाब ज्यादातर पहले पर निर्भर करता है कि मैं कितने अलग-अलग मॉड्यूल का उपयोग कर रहा हूं। अगर मैं केवल एक या दो का उपयोग करने जा रहा हूं, तो मैं अक्सर उपयोग करूंगा from... importक्योंकि यह बाकी की फ़ाइल में कम कीस्ट्रोक्स के लिए बनाता है, लेकिन अगर मैं कई अलग-अलग मॉड्यूल का उपयोग करने जा रहा हूं, तो मैं सिर्फ पसंद करता हूं importक्योंकि इसका मतलब है कि प्रत्येक मॉड्यूल संदर्भ स्व-दस्तावेजीकरण है। मैं देख सकता हूँ कि प्रत्येक प्रतीक चारों ओर से शिकार किए बिना कहाँ से आता है।

सामान्य रूप से मैं सादे आयात की स्व दस्तावेज़ीकरण शैली को पसंद करता हूं और केवल इससे बदल देता हूं .. आयात करता हूं जब मुझे कई बार मॉड्यूल का नाम टाइप करना होता है तो 10 से 20 से ऊपर बढ़ता है, भले ही केवल एक मॉड्यूल आयात किया जा रहा हो।


1

महत्वपूर्ण अंतर मुझे पता चला, जिनमें से एक आश्चर्यजनक रूप से कोई बारे में बात की गई है सादे का उपयोग कर कि आयात आप उपयोग कर सकते हैं private variableऔर private functionsआयातित मॉड्यूल है, जो साथ संभव नहीं है से से आयात बयान।

यहां छवि विवरण दर्ज करें

छवि में कोड:

setting.py

public_variable = 42
_private_variable = 141
def public_function():
    print("I'm a public function! yay!")
def _private_function():
    print("Ain't nobody accessing me from another module...usually")

plain_importer.py

import settings
print (settings._private_variable)
print (settings.public_variable)
settings.public_function()
settings._private_function()

# Prints:
# 141
# 42
# I'm a public function! yay!
# Ain't nobody accessing me from another module...usually

from_importer.py

from settings import *
#print (_private_variable) #doesn't work
print (public_variable)
public_function()
#_private_function()   #doesn't work

0

आयात मॉड्यूल - आपको मॉड्यूल से दूसरी चीज़ लाने के लिए अतिरिक्त प्रयासों की आवश्यकता नहीं है। इसमें अनावश्यक टाइपिंग जैसे नुकसान हैं

मॉड्यूल आयात से - कम टाइपिंग और अधिक नियंत्रण जिस पर किसी मॉड्यूल की वस्तुओं को एक्सेस किया जा सकता है। उस मॉड्यूल से एक नए आइटम का उपयोग करें जिसे आपको अपने आयात विवरण को अपडेट करना है।


0

वहाँ कुछ अंतर्निहित मॉड्यूल है कि ज्यादातर नंगे कार्य (होते हैं बेस 64 , गणित , ओएस , shutil , सिस , समय , ...) और यह निश्चित रूप से इन नंगे कार्य करने के लिए एक अच्छा अभ्यास है बाध्य कुछ नाम स्थान है और इस तरह की पठनीयता में सुधार अपने कोड। गौर कीजिए कि उनके नाम के बिना इन कार्यों के अर्थ को समझना कितना कठिन है:

copysign(foo, bar)
monotonic()
copystat(foo, bar)

जब वे कुछ मॉड्यूल से बंधे होते हैं:

math.copysign(foo, bar)
time.monotonic()
shutil.copystat(foo, bar)

कभी-कभी आपको विभिन्न मॉड्यूल ( json.load बनाम अचार.लोड ) के बीच संघर्ष से बचने के लिए नाम स्थान की भी आवश्यकता होती है


दूसरी ओर कुछ मॉड्यूल है कि ज्यादातर वर्गों को शामिल कर रहे हैं ( configparser , दिनांक , tempfile , zipfile , ...) और उनमें से कई अपने वर्ग के नाम स्वतः स्पष्ट पर्याप्त बनाने:

configparser.RawConfigParser()
datetime.DateTime()
email.message.EmailMessage()
tempfile.NamedTemporaryFile()
zipfile.ZipFile()

इसलिए एक बहस हो सकती है कि क्या आपके कोड में अतिरिक्त मॉड्यूल नामस्थान के साथ इन वर्गों का उपयोग कुछ नई जानकारी जोड़ता है या कोड को लंबा करता है।


0

मैं इसमें जोड़ना चाहूंगा, आयात कॉल के दौरान विचार करने के लिए कुछ व्यवस्थाएं हैं:

मेरे पास निम्नलिखित संरचना है:

mod/
    __init__.py
    main.py
    a.py
    b.py
    c.py
    d.py

main.py:

import mod.a
import mod.b as b
from mod import c
import d

dis.dis अंतर दिखाता है:

  1           0 LOAD_CONST               0 (-1)
              3 LOAD_CONST               1 (None)
              6 IMPORT_NAME              0 (mod.a)
              9 STORE_NAME               1 (mod)

  2          12 LOAD_CONST               0 (-1)
             15 LOAD_CONST               1 (None)
             18 IMPORT_NAME              2 (b)
             21 STORE_NAME               2 (b)

  3          24 LOAD_CONST               0 (-1)
             27 LOAD_CONST               2 (('c',))
             30 IMPORT_NAME              1 (mod)
             33 IMPORT_FROM              3 (c)
             36 STORE_NAME               3 (c)
             39 POP_TOP

  4          40 LOAD_CONST               0 (-1)
             43 LOAD_CONST               1 (None)
             46 IMPORT_NAME              4 (mod.d)
             49 LOAD_ATTR                5 (d)
             52 STORE_NAME               5 (d)
             55 LOAD_CONST               1 (None)

अंत में वे समान दिखते हैं (STORE_NAME प्रत्येक उदाहरण में परिणाम है), लेकिन यह ध्यान देने योग्य है यदि आपको निम्नलिखित चार परिपत्र आयातों पर विचार करने की आवश्यकता है:

उदाहरण 1

foo/
   __init__.py
   a.py
   b.py
a.py:
import foo.b 
b.py:
import foo.a
>>> import foo.a
>>>

यह काम

example2

bar/
   __init__.py
   a.py
   b.py
a.py:
import bar.b as b
b.py:
import bar.a as a
>>> import bar.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "bar\a.py", line 1, in <module>
    import bar.b as b
  File "bar\b.py", line 1, in <module>
    import bar.a as a
AttributeError: 'module' object has no attribute 'a'

कोई पाँसा नहीं

Example3

baz/
   __init__.py
   a.py
   b.py
a.py:
from baz import b
b.py:
from baz import a
>>> import baz.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "baz\a.py", line 1, in <module>
    from baz import b
  File "baz\b.py", line 1, in <module>
    from baz import a
ImportError: cannot import name a

इसी तरह का मुद्दा ... लेकिन x आयात y से स्पष्ट रूप से y के रूप में आयात आयात xy के समान नहीं है

Example4

qux/
   __init__.py
   a.py
   b.py
a.py:
import b 
b.py:
import a
>>> import qux.a
>>>

यह भी काम करता है


0

यह मेरी वर्तमान निर्देशिका की निर्देशिका संरचना है:

.  
└─a  
   └─b  
     └─c
  1. importबयान याद है सभी मध्यवर्ती नाम
    इन नामों को योग्य होना चाहिए :

    In[1]: import a.b.c
    
    In[2]: a
    Out[2]: <module 'a' (namespace)>
    
    In[3]: a.b
    Out[3]: <module 'a.b' (namespace)>
    
    In[4]: a.b.c
    Out[4]: <module 'a.b.c' (namespace)>
  2. from ... import ...बयान याद करते ही आयातित नाम
    यह नाम योग्य नहीं होना चाहिए :

    In[1]: from a.b import c
    
    In[2]: a
    NameError: name 'a' is not defined
    
    In[2]: a.b
    NameError: name 'a' is not defined
    
    In[3]: a.b.c
    NameError: name 'a' is not defined
    
    In[4]: c
    Out[4]: <module 'a.b.c' (namespace)>

  • नोट: बेशक, मैंने चरण 1 और 2 के बीच अपने पायथन कंसोल को पुनः आरंभ किया।

0

जैसा कि जान व्रोबेल उल्लेख करते हैं, विभिन्न आयातों का एक पहलू यह है कि किस तरह से आयातों का खुलासा किया जाता है।

मॉड्यूल mymath

from math import gcd
...

ममत का उपयोग :

import mymath
mymath.gcd(30, 42)  # will work though maybe not expected

अगर मैं gcdकेवल आंतरिक उपयोग के लिए आयात करता हूं , तो उपयोगकर्ताओं के लिए इसका खुलासा करने के लिए नहींmymath , यह असुविधाजनक हो सकता है। मेरे पास यह अक्सर होता है, और ज्यादातर मामलों में मैं "अपने मॉड्यूल को साफ रखना चाहता हूं"।

इसके बजाय का उपयोग करके इसे थोड़ा और अस्पष्ट करने के लिए जन व्रोबेल के प्रस्ताव के अलावा import math, मैंने एक प्रमुख अंडरस्कोर का उपयोग करके प्रकटीकरण से आयात को छिपाना शुरू कर दिया है:

# for instance...
from math import gcd as _gcd
# or...
import math as _math

बड़ी परियोजनाओं में यह "सबसे अच्छा अभ्यास" मुझे ठीक से नियंत्रित करने की अनुमति देता है कि बाद के आयातों का खुलासा क्या है और क्या नहीं है। यह मेरे मॉड्यूल को साफ रखता है और परियोजना के एक निश्चित आकार में वापस भुगतान करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.