2010-12-03 15 views
70

सबसे पहले: मुझे खेद है, मुझे पता है कि रिश्तेदार आयात के बारे में बहुत सारे प्रश्न हैं, लेकिन मुझे अभी कोई समाधान नहीं मिला। मैं निम्नलिखित निर्देशिका लेआउट का उपयोग करना चाहते हैं यदि संभव हो तो:रिश्तेदार आयात के लिए पायथन पैकेजिंग

myClass/ 
    __init__.py 
    test/ 
     demo.py 
     benchmark.py 
     specs.py 
    src/ 
     __init__.py 
     myClass.py 

अब मेरी प्रश्न हैं:

  • कैसे पैकेज के भीतर से परीक्षण फ़ाइलों को ठीक से myClass.py आयात करूँ?

  • क्या आप मेरा क्लास को libs/myClass में सबमिशन के रूप में लेते हैं या इसमें शामिल हैं/myClass को मानते हैं?

अब तक मुझे इसके लिए एक शानदार समाधान नहीं मिला। से मैं क्या Guido's Decision समझते हैं कि यह from ..src import myClass करने के लिए संभव हो जाना चाहिए लेकिन इस त्रुटि देगा:

ValueError: Attempted relative import in non-package

कौन सा रूप में यह संकुल के रूप में myClass इलाज नहीं करता लग रहा है। Reading the docs:

The __init__.py files are required to make Python treat the directories as containing packages;

यह मैं कुछ निर्दिष्ट करता पैकेज की स्क्रिप्ट, कर रहे हैं मैं .pth का उपयोग करना चाहिए याद कर रहा हूँ लगता है?

+6

@ ब्रेंट न्यू, हाँ, आप सही हैं, सापेक्ष आयात एक सतत विषय प्रतीत होता है और कुछ जवाब पढ़ने के बाद भी मुझे अपनी स्थिति का विशेष रूप से वर्णन करने का आग्रह महसूस हुआ। इस क्यू को दिखाने के बाद, #python आईआरसी चैनल पर कुछ लोगों ने फ्लैट निर्देशिका संरचना का उपयोग करने की सिफारिश की: "बहुत से लोग पाइथन अर्थपूर्ण नामस्थान जानकारी के लिए निर्देशिकाओं और फ़ाइलों का उपयोग करना चाहते हैं। यह सबसे अच्छा है और करना पाइथन क्या चाहता है। " http://jcalderone.livejournal.com/39794.html – eerne

+8

कोई भी वास्तविक वास्तविकता पैकेज के साथ, या कुछ सम्मेलनों के बाद, कुछ वास्तविक दुनिया के पैकेजों के लिए एक लिंक प्रदान कर सकता है? (आदर्श रूप से github पर) – eerne

+1

क्या 'test' निर्देशिका में '__init __। py' है? 'ValueError: गैर-पैकेज में सापेक्ष आयात का प्रयास करने से संबंधित हो सकता है। – jfs

उत्तर

0

Intra-package-references वर्णन करता है कि test/* से कैसे करें। बाहर से पैकेज आयात करने के लिए, आपको आयात करने से पहले कोड में sys.path सूची में आयात करने से पहले PYTHONPATH पर्यावरण चर में अपना पथ जोड़ना चाहिए।

क्यों from ..src import myClass विफल रहता है: शायद, src एक पायथन पैकेज नहीं है, आप वहां से आयात नहीं कर सकते हैं। ऊपर वर्णित अनुसार आपको इसे पाइथन पथ में जोड़ना चाहिए।

+0

सापेक्ष आयात हर समय किया जाता है। कई पैकेजों में उनके साथ छोटे उप पैकेज होते हैं और सापेक्ष आयात पर भरोसा करते हैं। ओपी बाहरी पैकेजों का संदर्भ देने के लिए नहीं पूछ रहा है। वह एक पैकेज के भीतर एक और उप पैकेज का संदर्भ देने के लिए पूछ रहा है। – cstrutton

41

ValueError: Attempted relative import in non-package

मतलब है कि आप मॉड्यूल में सापेक्ष आयात का उपयोग करने का प्रयास करते हैं जो पैकेज नहीं है। फ़ाइल के साथ इसकी समस्या जिसमें from ... import कथन है, न कि वह फ़ाइल जिसे आप आयात करने का प्रयास कर रहे हैं।

तो यदि आप अपने परीक्षणों में सापेक्ष आयात कर रहे हैं, उदाहरण के लिए, आपको अपने परीक्षणों को अपने पैकेज का हिस्सा बनना चाहिए। इसका मतलब यह है

  1. __init__.py शामिल करने से वे कुछ बाहर स्क्रिप्ट से चल रहा है/
  2. परीक्षण करने के लिए nosetests की तरह,

आप python myClass/test/demo.py के रूप में कुछ चलाते हैं, रिश्तेदार आयात भी काम नहीं करेगा जब से तुम डेमो मॉड्यूल चल रहे हैं पैकेज के रूप में नहीं। सापेक्ष आयात की आवश्यकता है कि उनका उपयोग करने वाले मॉड्यूल को या तो पैकेज मॉड्यूल, from myClass.test.demo import blabla, या सापेक्ष आयात के रूप में आयात किया जा रहा है।

25

पिछली रात खोज के घंटों के बाद मुझे पाइथन में सापेक्ष आयात का जवाब मिला !! या कम से कम एक आसान समाधान। इसे किसी अन्य मॉड्यूल से बुलाए जाने वाले मॉड्यूल के लिए इसे ठीक करने का सबसे अच्छा तरीका है। तो कहें कि आप सब-पैकेज खिलौने की जड़ पर MyClass फ़ोल्डर में myClass.py आयात करने के लिए demo.py चाहते हैं, जिसमें दो अन्य कॉल करने वाली फ़ाइल होनी चाहिए।मैं जो काम करता हूं उससे काम करने वाली निर्देशिका को हमेशा मुख्य माना जाता है, इसलिए यदि आप demo.py स्क्रिप्ट के साथ demo.py से आयात का परीक्षण करते हैं, तो आपको वह त्रुटि प्राप्त होगी। इसे समझने के लिए:

फ़ोल्डर hierarcy:

myClass/ 
    main.py #arbitrary name, can be anything 
    test/ 
     __init__.py 
     demo.py 
    src/ 
     __init__.py 
     myClass.py 

myClass.py:

def randomMaths(x): 
    a = x * 2 
    y = x * a 
    return y 

demo.py:

from ..src import myClass 

def printer(): 
    print(myClass.randomMaths(42)) 

main.py:

import test.demo 

demo.printer() 

यदि आप दुभाषिया में demo.py चलाते हैं, तो आप एक त्रुटि उत्पन्न करेंगे, लेकिन main.py चलाना नहीं होगा। यह थोड़ा गड़बड़ है, लेकिन यह काम करता है: डी

+3

मैं पाइथन 2.7 का उपयोग कर रहा हूं और मुझे केवल उपरोक्त कोड तीन चीजें करके काम करने के लिए मिला है। सबसे पहले, उस स्तर पर जहां main.py है, मैंने एक '__init __। Py' जोड़ा। दूसरा, मैंने demo.printer() को 'test.demo.printer()' में बदल दिया। तीसरा, मैंने main.py के ऊपर निर्देशिका बदल दी और 'python -m myClass.main' चलाया। अन्यथा, यह मेरे लिए एक बहुत ही उपयोगी जवाब था। :) – Paul

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