2015-06-05 3 views
5

निम्नलिखित परियोजना संरचना पर विचार करेंपरीक्षण निर्देशिका में __init__.py होने पर आयात पाइथन नाक के साथ क्यों काम करता है? <code>test_a.py</code> मॉड्यूल <code>a</code> आयात करने के साथ</p> <pre><code>a.py test/ test_a.py </code></pre> <p>:

import a 

जैसी उम्मीद थी, आयात त्रुटि में test निर्देशिका परिणामों में nosetests चल:

ERROR: Failure: ImportError (No module named a) 

हालांकि , मैंने देखा कि एक खालीजोड़ना test निर्देशिका मेंफ़ाइल nosetests के साथ आयात कार्य करती है (लेकिन जब आप पाइथन के साथ test_a.py चलाते हैं)। क्या आप समझा सकते हैं क्यों?

मैं समझता हूं कि __init__.pytest एक पैकेज बनाता है। लेकिन क्या इसका मतलब यह है कि आयात में लुकअप में पैकेज युक्त निर्देशिका शामिल है?

+0

http://stackoverflow.com/questions/448271/what-is-init-py-for – Mir

+3

@ मेरी समझ में आता है कि '__init __। Py' । मुझे समझ में नहीं आता कि यह अन्य मॉड्यूल के आयात को क्यों प्रभावित करता है। – vitaut

+0

क्योंकि अगर यह वहां नहीं था, तो आप दुर्घटना से किसी भी निर्देशिका को आयात कर सकते हैं, जो बेकार के बगल में होगा। इसकी तरह एक प्रोग्रामेटिक जांच है। – Kris

उत्तर

5

निर्देशिका में एक __init__.py फ़ाइल की उपस्थिति एक अजगर package में सिर्फ एक सादे पुराने निर्देशिका से test बदल देती है। इसका sys.path पर प्रभाव पड़ता है।

इस तरह से अपनी test_a.py मॉड्यूल संशोधित करें:

import sys 

def test_thing(): 
    for i, p in enumerate(sys.path): 
     print i, p 

try: 
    import a 
except ImportError: 
    print('caught import error') 

फिर परीक्षण निर्देशिका से nosetests -s चल रहा है, के साथ और वहाँ में एक __init__.py बिना प्रयास करें।

नोट: यह परीक्षण धावक है जो sys.path munges है। और यह the second "Note" of this section here (धन्यवाद @ डेविडिज्म) में प्रलेखित है। पैकेज संरचना के साथ और बिना python test_a.py चलाकर आप वहां कोई भी परिवर्तन नहीं देखेंगे।

+3

मैं समझता हूं, लेकिन यह आयात लुकअप को कैसे प्रभावित करता है? – vitaut

+0

दाएं। मैंने और विस्तार जोड़ा है। – wim

+1

[py.test (जो नुकीले से निकलते हैं) इसे भी समझाते हैं] (http://pytest.org/latest/goodpractises.html#choosing-a-test-layout-import-rules) – davidism

2

मैंने नाक मॉड्यूल के सॉस कोड में देखा और यही कारण है कि।

def importFromPath(self, path, fqname): 
    """Import a dotted-name package whose tail is at path. In other words, 
    given foo.bar and path/to/foo/bar.py, import foo from path/to/foo then 
    bar from path/to/foo/bar, returning bar. 
    """ 
    # find the base dir of the package 
    path_parts = os.path.normpath(os.path.abspath(path)).split(os.sep) 
    name_parts = fqname.split('.') 
    if path_parts[-1] == '__init__.py': 
     path_parts.pop() 
    path_parts = path_parts[:-(len(name_parts))] 
    dir_path = os.sep.join(path_parts) 
    # then import fqname starting from that dir 
    return self.importFromDir(dir_path, fqname) 

def importFromDir(self, dir, fqname): 
    """Import a module *only* from path, ignoring sys.path and 
    reloading if the version in sys.modules is not the one we want. 
    """ 
    dir = os.path.normpath(os.path.abspath(dir)) 

आपके मामले में जब importFromDir importFromPath से कहा जाता है, 'निर्देशिका' निर्देशिका __init__.py निर्देशिका से ऊपर एक स्तर पर है। इसलिए यही कारण है कि __init__.py आपके परीक्षण में 'आयात करें' काम

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

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