2012-05-08 19 views
9

मान लीजिए मैं एक पैकेज है कि मॉड्यूल शामिल है:अजगर मॉड्यूल

SWS/ 
    __init.py__ 
    foo.py 
    bar.py 
    time.py 

और मॉड्यूल एक-दूसरे में समाहित कार्यों का उल्लेख करने की जरूरत है। ऐसा लगता है कि मैं अपने time.py मॉड्यूल के साथ समस्याओं में भाग लेता हूं क्योंकि एक मानक मॉड्यूल है जो एक ही नाम से जाता है।

उदाहरण के लिए, मामला यह है कि मेरे foo.py मॉड्यूल दोनों मेरे SWS.time और मानक अजगर time मॉड्यूल की आवश्यकता है, मैं मुसीबत में पड़ के बाद से दुभाषिया पैकेज के अंदर देखने के लिए और मेरे time.py मॉड्यूल लगता है इससे पहले कि यह मानक time मॉड्यूल भर आता होगा ।

क्या इसके आसपास कोई रास्ता है? क्या यह कोई स्थिति नहीं है और क्या मॉड्यूल नामों का पुन: उपयोग नहीं किया जाना चाहिए?

पैकेज दर्शन पर कोई समाधान और राय यहां उपयोगी होगी।

+2

मुझे लगता है कि यह बहुत स्पष्ट है कि आपको मानक पायथन मॉड्यूल नामों का पुन: उपयोग नहीं करना चाहिए। यह सिर्फ परेशानी के लिए पूछ रहा है। – Cryptite

+3

यह स्पष्ट क्यों है? MikeWyatt

+0

httplib/httplib2 और urllib/urllib2 को देखें। यह पुस्तकालयों की एक उग्र दुनिया के लिए बनाता है, लेकिन टकराव और अनिश्चित व्यवहार नाम देने के लिए यह बेहतर है। –

उत्तर

10

मानक कार्यों/कक्षाओं/मॉड्यूल/पैकेजों के नामों का पुन: उपयोग करना कभी अच्छा विचार नहीं है। जितना संभव हो उससे बचने की कोशिश करें। हालांकि आपकी स्थिति में साफ कामकाज हैं।

व्यवहार आप देखते हैं, अपने SWS.time बजाय stdlib time के आयात, प्राचीन अजगर संस्करणों (2.x) में import के शब्दों के कारण है। इसे ठीक करने के लिए:

from __future__ import absolute_import 

फ़ाइल के शीर्ष पर। यह python3.x के import के अर्थशास्त्र को बदल देगा, जो अधिक समझदार हैं। उस स्थिति में कथन:

import time 

केवल शीर्ष-स्तरीय मॉड्यूल का संदर्भ देगा। तो दुभाषिया पैकेज के अंदर उस आयात को निष्पादित करते समय आपके SWS.time मॉड्यूल पर विचार करेगा, लेकिन यह केवल मानक लाइब्रेरी का उपयोग करेगा।एक पूर्ण आयात का उपयोग करना

from . import time 
  • : एक स्पष्ट रिश्तेदार आयात का उपयोग करना

    • :

      एक मॉड्यूल अंदर अपने पैकेज की जरूरत है SWS.time आयात करने के लिए यदि आप का विकल्प है:

      import SWS.time as time 
      

    तो, अपने foo.py होगा कुछ की तरह:

    from __future__ import absolute_import 
    
    import time 
    
    from . import time as SWS_time 
    
  • +2

    मैं तर्क दूंगा कि यह एक बुरा विचार नहीं है * जब मॉड्यूल का नाम नामस्थान की उपस्थिति में है, जैसे पैकेज। यह पीईपी 328 की भावना है। नीचे मेरा जवाब देखें। – OozeMeister

    0

    हाँ, वास्तव में इसके आसपास कोई अच्छा तरीका नहीं है। मानक पैकेज जैसे अपने मॉड्यूल नाम न करने का प्रयास करें। यदि आप वास्तव में अपने मॉड्यूल time पर कॉल करना चाहते हैं, तो मैं इसके बजाय _time.py का उपयोग करने की अनुशंसा करता हूं। यहां तक ​​कि अगर ऐसा करने का कोई तरीका था, तो यह आपके कोड को 2 बार मॉड्यूल में आने पर पढ़ने और भ्रमित करने में कठोर बना देगा।

    4

    जैसा कि अन्य ने कहा है, यह आम तौर पर एक बुरा विचार है।

    कहा जा रहा है, आप संभावित समाधानों, या समस्या का एक बेहतर समझ के लिए देख रहे हैं, मैं सुझाव है कि आप निम्नलिखित अतः सवाल पढ़ें:

    4

    यह अजगर के किस संस्करण का उपयोग कर रहे पर निर्भर करता है। यदि आपका लक्षित पायथन संस्करण 2.4 या पुराना है (2015 में, मुझे यकीन है कि नहीं), तो हाँ यह खराब अभ्यास होगा क्योंकि दो मॉड्यूल को अलग करने के लिए कोई रास्ता नहीं है (हैक के बिना)।

    हालांकि, पाइथन 2.5+ में, मुझे लगता है कि मानक lib मॉड्यूल नाम का उपयोग पैकेज नामस्थान में बिल्कुल ठीक है; वास्तव में, यह the spirit of PEP328 है।

    चूंकि पाइथन की लाइब्रेरी फैलती है, अधिक से अधिक मौजूदा पैकेज आंतरिक मॉड्यूल अचानक दुर्घटना से मानक लाइब्रेरी मॉड्यूल छाया करते हैं। पैकेजों के अंदर यह एक विशेष रूप से कठिन समस्या है क्योंकि निर्दिष्ट करने का कोई तरीका नहीं है कि कौन सा मॉड्यूल मतलब है। अस्पष्टता को हल करने के लिए, यह प्रस्तावित किया जाता है कि foo हमेशा sys.path से पहुंचने योग्य मॉड्यूल या पैकेज होगा। इसे पूर्ण आयात कहा जाता है।

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

    क्योंकि इस अर्थ विज्ञान में एक परिवर्तन का प्रतिनिधित्व करता है, पूर्ण आयात from __future__ import absolute_import

    SWS.time के उपयोग के माध्यम अजगर 2.5 और 2.6 में वैकल्पिक होगा स्पष्ट रूप से नहींtime के रूप में और के एक पाठक के रूप में एक ही बात है कोड, मैं SWS.time की अपेक्षा करता हूं न कि केवल time का उपयोग करें, बल्कि इसे किसी भी तरीके से विस्तारित करने के लिए।

    तो, अगर SWS.foo जरूरतों SWS.time आयात करने के लिए, तो यह निरपेक्ष पथ का उपयोग करना चाहिए:

    # in SWS.foo 
    
    # I would suggest renaming *within* 
    # modules that use SWS.time so that 
    # readers of your code aren't confused 
    # with which time module you're using 
    from SWS import time as sws_time 
    

    या, यह Bakuriu के जवाब में के रूप में एक स्पष्ट रिश्तेदार आयात का उपयोग करना चाहिए:

    # in SWS.foo 
    
    from . import time as sws_time 
    

    यदि आपको SWS.time मॉड्यूल के भीतर मानक lib time मॉड्यूल आयात करने की आवश्यकता है, तो आपको सबसे पहले भविष्य की सुविधा आयात करने की आवश्यकता होगी (केवल पायथन के लिए 2।5 +; अजगर 3 + डिफ़ॉल्ट रूप से करता):

    # inside of SWS.time 
    from __future__ import absolute_import 
    
    import time 
    
    time.sleep(28800) # time for bed 
    

    नोट:from __future__ import absolute_imports केवल मॉड्यूल है कि भविष्य सुविधा आयात किया जाता है भीतर आयात बयानों को प्रभावित करेगा और नहीं किसी अन्य मॉड्यूल (प्रभावित करेगा कि होगा के रूप में यदि कोई अन्य मॉड्यूल सापेक्ष आयात पर निर्भर करता है तो हानिकारक रहें)।

    +0

    ध्यान दें कि पीईपी 8 से आपका उद्धरण ** अप्रचलित ** है। पीईपी 8 * का वर्तमान संस्करण रिश्तेदार आयात का उपयोग करने का समर्थन करता है *: उद्धरण: * स्पष्ट रिश्तेदार आयात पूर्ण आयात के लिए एक स्वीकार्य विकल्प हैं, खासकर जब जटिल पैकेज लेआउट से निपटने पर पूर्ण आयात का उपयोग अनावश्यक रूप से वर्बोज़ * – Bakuriu

    +1

    @ बाकुरी, अच्छी तरह से डर्न होगा। मुझे नहीं पता था कि पीईपी इस तरह बदल सकते हैं। मैं अपना जवाब अपडेट करूंगा। मैं अभी भी अपना तर्क बनाए रखूंगा, हालांकि, एक पैकेज मॉड्यूल जिसका नाम शीर्ष-स्तरीय stdlib मॉड्यूल जैसा ही है, केवल स्वीकार्य नहीं है, बल्कि प्रोत्साहित किया जाता है। – OozeMeister

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