2010-07-06 15 views
9

पायथन में, यदि आपको किसी भिन्न पैकेज से मॉड्यूल की आवश्यकता है तो आपको इसे आयात करना होगा। जावा पृष्ठभूमि से आ रहा है, जो समझ में आता है।जब आप पूर्ण नाम का उपयोग करने की आवश्यकता हो तो आयात क्यों करें?

import foo.bar 

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

यह from foo import bar होने के लिए थोड़ा अनावश्यक लगता है जब import foo.bar ऐसा करना चाहिए। इसके अलावा थोड़ा अस्पष्ट क्यों था जब मैं पूर्ण नाम का उपयोग करने जा रहा था।

+0

"आयात करने की आवश्यकता" से आपका क्या मतलब है? क्या आप foo.bar को पहले आयात करने के बिना काम करने की उम्मीद करते हैं? आप कैसे जानेंगे कि foo जावा में सामान्य चर – mb14

+4

@ mb14 की बजाय मॉड्यूल है, आप सीधे अपने कोड में पैकेज नाम के साथ पूरी तरह से योग्य क्लास नाम का उपयोग करके आयात किए बिना किसी अन्य पैकेज में कक्षाओं का उपयोग कर सकते हैं। उदाहरण के लिए, आप अपने स्रोत में जावा की सूची इंटरफ़ेस को "java.util.List" के रूप में संदर्भित कर सकते हैं या इसे पहले आयात कर सकते हैं, फिर इसे "सूची" के रूप में देखें। जिस तरह से पाइथन जावा से आ रहा है, ऐसा लगता है कि आप java.util.List आयात कर रहे हैं, फिर भी आपको अपने कोड में "सूची" के बजाय "java.util.List" लिखना होगा। – Jeff

उत्तर

23

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

import java.util.Set; 

बारे में यह संकलक कि उस फ़ाइल भर, जब आप Set लिखते हैं, आप मतलब java.util.Set बताता है। और यदि आप s.add(o) लिखते हैं, जहां sSet प्रकार का ऑब्जेक्ट है, तो कंपाइलर (या बल्कि, लिंकर) बाहर निकलता है और विधि Set.class में पाता है और इसके संदर्भ में रखता है।

लेकिन अजगर में,

(है कि एक बना हुआ मॉड्यूल, जिस तरह से होता है) कुछ पूरी तरह से अलग करता है। चूंकि पाइथन गतिशील संकल्प के साथ एक व्याख्या की गई भाषा है, इसलिए बाहर जाने और util.set मॉड्यूल के कोड को देखने के लिए कोई कंपाइलर नहीं है। पाइथन में क्या होता है कि दुभाषिया util नामक एक मॉड्यूल के साथ set नामक एक मॉड्यूल के साथ एक पैकेज ढूंढता है और पैकेज और मॉड्यूल लोड करता है, और इस प्रक्रिया में, यह वास्तव में set नामक विशेषता के साथ util नामक ऑब्जेक्ट बनाता है। (यह सही है, पाइथन में संकुल और मॉड्यूल वास्तविक प्रथम श्रेणी की वस्तुएं हैं।) आप

util = __import__('util.set') 

जहां समारोह __import__ एक वस्तु जो एक विशेषता set कहा जाता है का उत्पादन के रूप में ऊपर बयान के बारे में सोच सकता है। असल में, वास्तव में ऐसा होता है जब आप मॉड्यूल आयात करते हैं - documentation for __import__ देखें। तो आप देखते हैं, जब आप पाइथन मॉड्यूल आयात करते हैं, तो आपको वास्तव में जो मिलता है वह शीर्ष-स्तर पैकेज, util से संबंधित एक ऑब्जेक्ट है, और set तक पहुंच प्राप्त करने के लिए आपको उसमें जाना होगा।

के रूप में कम से कम एक अन्य जवाब में उल्लेख किया है, आप

from util import set 

या

import util.set as set 

लिख सकता है यह अभी भी उस में मॉड्यूल set साथ पैकेज util आयात करता है, लेकिन इसके बजाय एक चर बनाने का वर्तमान क्षेत्र में util, यह एक चर set बनाता है जो util.set को संदर्भित करता है। परदे के पीछे, इस तरह की तरह

_util = __import__('util', fromlist='set') 
set = _util.set 
del _util 
पूर्व के मामले में

, या

बाद में
_util = __import__('util.set') 
set = _util.set 
del _util 

काम करता है (हालांकि दोनों तरीकों से अनिवार्य रूप से एक ही बात करते हैं)। यह रूप अर्थात्मक रूप से जावा की तरह अधिक है; यह किसी उपनाम (set) को उस चीज़ पर परिभाषित करता है जो आम तौर पर पूरी तरह से योग्य नाम (util.set) द्वारा केवल पहुंच योग्य होगा।

6

आप इसे छोटा कर सकते हैं, अगर आप चाहते हैं:

import foo.bar as whateveriwant 

पूर्ण नाम का उपयोग एक दूसरे को clobbering से समान नाम वाले submodules के साथ दो संकुल को रोकता है।

+1

+1, ओपी क्या ढूंढ रहा है इसके लिए यह सही उत्तर है। शायद "जो भी" के बजाय "बार" कहने के लिए संपादित करें? इससे यह और स्पष्ट हो सकता है कि यह मांग की गई कार्यक्षमता प्रदान करता है। – Cam

+3

यह सही उत्तर के करीब आता है, लेकिन व्याख्या नहीं करता है * क्यों * पायथन इस व्यवहार को प्रदर्शित करता है। – Philipp

+1

और यह 'foo आयात बार' से थोड़ा अधिक वर्बोज़ है। "foo.bar को बार के रूप में आयात करें" == 21 वर्ण, "foo आयात बार से" == 1 9 वर्ण। – JAB

3

आप थोड़ा उलझन में हैं कि पाइथन कैसे काम करता है। (मैं भी पहली बार शुरू हुआ था।) पायथन में, आप जावा में विपरीत, पूर्ण नाम से मॉड्यूल के भीतर कुछ भी नहीं देख सकते हैं; आयातित आइटम का जिक्र करने की योजना बनाने के बावजूद आपको पहले मॉड्यूल आयात करना होगा। math या math.sqrt आयात किए बिना दुभाषिया में math.sqrt(5) टाइप करने का प्रयास करें और देखें कि क्या होता है।

वैसे भी ... कारण import foo.bar आपको के बजाय foo.bar का उपयोग करने की आवश्यकता है, जो आकस्मिक नामस्थान संघर्षों को रोकने के लिए है। उदाहरण के लिए, यदि आप import foo.bar करते हैं, और फिर import baz.bar क्या करते हैं?

आप निश्चित रूप से import foo.bar as bar (यानी एलियासिंग) करना चुन सकते हैं, लेकिन यदि आप ऐसा कर रहे हैं तो आप from foo import bar का उपयोग कर सकते हैं। (संपादित करें: जब आप विधियों और चर आयात करना चाहते हैं। तब आपको from ... import ... वाक्यविन्यास का उपयोग करना होगा। इसमें ऐसे उदाहरण शामिल हैं जहां आप बिना किसी विधि के एक विधि या चर आयात करना चाहते हैं, यानी आप import foo.bar नहीं कर सकते हैं यदि bar एक विधि है या परिवर्तनीय।)

+0

'आयात के रूप में foo.bar आयात करें' को कुछ तकनीकी कारणों से 'foo आयात बार' से अधिक पसंद किया जाता है जिसे मैं और नहीं पा रहा हूं। – Philipp

+1

@ फिलिप: यदि हां, तो यह मेरे लिए खबर है। –

+1

@ फिलिप: http://docs.python.org/py3k/howto/doanddont.html#from-module-import-name1-name2 वहां कोई वरीयता का कोई उल्लेख नहीं है। वास्तव में, आप सभी मामलों में पूर्व का उपयोग नहीं कर सकते हैं, क्योंकि जब आप विधियों या डेटा सदस्यों को आयात करने का प्रयास करते हैं तो यह विफल हो जाता है। आकस्मिक नामस्थान संघर्ष का उल्लेख करने के लिए – JAB

1

जावा के अलावा, पाइथन import foo.bar में घोषित करता है कि आप foo.bar द्वारा निर्दिष्ट चीज़ का उपयोग करने जा रहे हैं।

यह पायथन के दर्शन के साथ मेल खाता है जो स्पष्ट रूप से स्पष्ट है। ऐसी प्रोग्रामिंग भाषाएं हैं जो इंटर-मॉड्यूल निर्भरताओं को जावा से अधिक स्पष्ट बनाती हैं, उदाहरण के लिए एडा।

पूर्ण नाम का उपयोग करके विभिन्न मॉड्यूल से आने वाले नाम के साथ परिभाषाओं को असंबद्ध करना संभव हो जाता है।

3

पायथन में, आयात करने से संकेत मिलता है कि आप कुछ उपयोग कर सकते हैं। आयात वास्तव में मॉड्यूल स्तर पर कोड निष्पादित करता है। आप उस पल के रूप में आयात के बारे में सोच सकते हैं जहां कार्यों को 'व्याख्या' और बनाया गया है। कोई भी कोड जो _____init_____.py स्तर में है या फ़ंक्शन या क्लास परिभाषा के अंदर नहीं है तब होता है।

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

+0

ध्यान दें कि जब एक मॉड्यूल या पैकेज कई बार आयात किया जाता है, तो मॉड्यूल में किसी निष्पादन योग्य कोड या पैकेज की '__init __। Py' फ़ाइल केवल पहले आयात के लिए निष्पादित की जाएगी। जो अच्छा है। – JAB

4

वहाँ मानक पुस्तकालय में एक मॉड्यूल io कहा जाता है:

In [84]: import io 

In [85]: io 
Out[85]: <module 'io' from '/usr/lib/python2.6/io.pyc'> 

भी scipy में एक मॉड्यूल io कहा जाता है:

In [95]: import scipy.io 

In [96]: scipy.io 
Out[96]: <module 'scipy.io' from '/usr/lib/python2.6/dist-packages/scipy/io/__init__.pyc'> 

आप एक ही लिपि में दोनों मॉड्यूल का उपयोग करना चाहता है तो , तो नामस्थान दो अलग करने के लिए एक सुविधाजनक तरीका है।

In [97]: import this 
The Zen of Python, by Tim Peters 
... 
Namespaces are one honking great idea -- let's do more of those! 
3

पायथन दर्शन का हिस्सा explicit is better than implicit है। पाइथन स्वचालित रूप से पहली बार आयात कर सकता है जब आप पैकेज से कुछ एक्सेस करने का प्रयास करते हैं, लेकिन यह स्पष्ट नहीं है।

मैं यह भी अनुमान लगा रहा हूं कि आयात प्रारंभ होने पर पैकेज प्रारंभिकता अधिक कठिन होगी, क्योंकि यह कोड में लगातार नहीं किया जाएगा।

1

आपको पूरा नाम उपयोग करने की ज़रूरत नहीं है। इन

from foo import bar 

import foo.bar as bar 

import foo.bar 
bar = foo.bar 

from foo import * 

कुछ कारण हैं जिनकी वजह स्पष्ट आयात अच्छे हैं में से एक का प्रयास करें:

  • वे मानव और उपकरण क्या पैकेज अपने मॉड्यूल पर निर्भर करता है के लिए संकेत मदद करते हैं।
  • वे गतिशील रूप से निर्धारित करने के ऊपरी हिस्से से बचते हैं कि रन पैकेज पर कौन से पैकेज लोड किए जाएंगे (और संभवतः संकलित)।
  • वे (sys.path के साथ) अलग-अलग नामस्थानों से विरोधाभासी नामों के साथ प्रतीकों को अलग-अलग पहचानते हैं।
  • वे प्रोग्रामर को उस नामस्थान में प्रवेश करने के बारे में कुछ नियंत्रण देते हैं जिसमें वह काम कर रहा है।
संबंधित मुद्दे

 संबंधित मुद्दे