एक उपनिर्देशिका से एक फ़ाइल आयात करें?


456

मेरे पास एक फ़ाइल है tester.py, जिस पर स्थित है /project

/projectएक उपनिर्देशिका कहा जाता है lib, नामक एक फाइल के साथ BoxTime.py:

/project/tester.py
/project/lib/BoxTime.py

मैं आयात करना चाहते हैं BoxTimeसे tester। मैंने यह कोशिश की है:

import lib.BoxTime

जिसके परिणामस्वरूप:

Traceback (most recent call last):
  File "./tester.py", line 3, in <module>
    import lib.BoxTime
ImportError: No module named lib.BoxTime

किसी भी विचार कैसे BoxTimeउपनिर्देशिका से आयात करने के लिए ?

संपादित करें

__init__.pyसमस्या थी, लेकिन भूल नहीं है का उल्लेख करने BoxTimeके रूप में lib.BoxTime, या उपयोग:

import lib.BoxTime as BT
...
BT.bt_function()

जवाबों:


536

यहां पैकेज प्रलेखन (धारा 6.4) पर एक नज़र डालें: http://docs.python.org/tutorial/modules.html

संक्षेप में, आपको नाम से एक रिक्त फ़ाइल डालने की आवश्यकता है

__init__.py

"lib" निर्देशिका में।


59
यह हैकिंग क्यों महसूस करता है ? यह तरीका है कि अजगर सुरक्षित / उपलब्ध आयात निर्देशिकाओं को चिह्नित करता है।
IAbstract

7
न केवल यह सुरक्षित / उपलब्ध आयात निर्देशिकाओं को चिह्नित करता है, बल्कि निर्देशिका नाम आयात करते समय कुछ आरंभीकरण कोड चलाने का एक तरीका भी प्रदान करता है।
सज्जाद

32
हां, यह हैकरी और यहां तक ​​कि गंदा है, और मेरी राय में भाषा को फाइलसिस्टम में फाइल लोड करने का अपना तरीका नहीं थोपना चाहिए। PHP में हमने यूजरलैंड कोड को एक ऑटोपेडिंग फ़ंक्शन को पंजीकृत करने की समस्या को हल किया है जो कि नामस्थान / वर्ग गायब होने पर कहा जाता है। तब समुदाय ने PSR-4 मानक का निर्माण किया है और संगीतकार ने इसे लागू किया है, और आजकल किसी को भी इसके बारे में चिंता करने की ज़रूरत नहीं है। और कोई बेवकूफ हार्डकोड __init__फ़ाइल नहीं है (लेकिन यदि आप इसे चाहते हैं, तो बस एक ऑटोलोडिंग हुक पंजीकृत करें! यह हैक और हैक के बीच अंतर है )।
मॉर्गन टोवरे क्विलिंग

4
@ import sys, os; sys.path.insert(0, os.path.abspath('..')); from sibling_package.hacks import HackyHackHack
औरेलियोनोम्स

4
अजगर एक गन्दा है :)
जिमी पेटर्सन

174
  • नाम से एक उपनिर्देशिका बनाएँ lib
  • नाम से एक खाली फ़ाइल बनाएँ lib\__init__.py
  • में lib\BoxTime.pyएक समारोह लिखने foo()इस तरह:

    def foo():
        print "foo!"
  • उपरोक्त निर्देशिका में अपने क्लाइंट कोड में lib, लिखें:

    from lib import BoxTime
    BoxTime.foo()
  • अपना क्लाइंट कोड चलाएं। तुम्हे मिल जाएगा:

    foo!

बहुत बाद में - लिनक्स में, यह इस तरह दिखेगा:

% cd ~/tmp
% mkdir lib
% touch lib/__init__.py
% cat > lib/BoxTime.py << EOF
heredoc> def foo():
heredoc>     print "foo!"
heredoc> EOF
% tree lib
lib
├── BoxTime.py
└── __init__.py

0 directories, 2 files
% python 
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from lib import BoxTime
>>> BoxTime.foo()
foo!

2
क्या आप पायथन प्रलेखन के लिए एक लिंक प्रदान कर सकते हैं जहाँ यह समझाया गया है? धन्यवाद!
ज़ेनन

5
कि लिंक क्लिक करने योग्य लेट्स मेक: docs.python.org/3/tutorial/modules.html#packages
गेब्रियल स्टेपल्स

पैकेज को लागू करने के लिए अच्छा वॉकथ्रूlib
MasterControlProgram

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

अंडरस्कोर => python3 (टिप्पणी संपादित करने के लिए बहुत देर हो चुकी है)
अलेक्जेंडर स्टोह

68

आप इसमें सम्मिलित करने का प्रयास कर सकते हैं sys.path:

sys.path.insert(0, './lib')
import BoxTime

11
यदि आप किसी कारण से या नहीं बना नहीं होगा सकता है यह बहुत अच्छा है init .py फ़ाइल।
जेपीहल

1
यदि आप "प्रोजेक्ट" निर्देशिका से अजगर चलाते हैं तो यह काम करता है। ""। आपकी वर्तमान कार्यशील निर्देशिका के सापेक्ष व्याख्या की जाती है, उस निर्देशिका के सापेक्ष नहीं जहां आप जिस फ़ाइल को क्रियान्वित कर रहे हैं वह जीवन है। आप कहते हैं cd /data, python ../project/tester.py। तब यह काम नहीं करेगा।
सुबह का समय

2
इसने मेरे लिए काम किया। मैं इसे एक init .py फ़ाइल पर पसंद करता हूं , यह क्लीनर आयात विवरण के लिए बनाता है।
टेलर इवांसन

5
यह बहुत बेहतर काम करता है और "सही" समाधान है। init .py उन बोटो जैसे पैकेजों को गड़बड़ करता है जिनमें मॉड्यूल के साथ अपने स्वयं के बाल फ़ोल्डर होते हैं।
डेव डॉपसन

1
@jpihl आपको उस फ़ोल्डर से अजगर आयात मॉड्यूल की अनुमति देने के लिए __init__.py नाम की एक कम से कम एक एमी फ़ाइल बनानी होगी । मैंने उस समाधान की कोशिश की है और पूरी तरह से काम करता है (v2.7.6)।
m3nda

31

मैं इसे नीचे लिख रहा हूं क्योंकि सभी को लगता है कि आपको एक libनिर्देशिका तैयार करनी होगी ।

आपको अपनी उप-निर्देशिका का नाम देने की आवश्यकता नहीं है lib। आप इसे anythingप्रदान कर सकते हैं, बशर्ते कि आप इसमें डाल __init__.pyदें।

आप एक शेल शेल में निम्न कमांड दर्ज करके ऐसा कर सकते हैं:

$ touch anything/__init__.py 

तो अब आपके पास यह संरचना है:

$ ls anything/
__init__.py
mylib.py

$ ls
main.py

तो फिर तुम आयात कर सकते हैं mylibमें main.pyइस तरह:

from anything import mylib 

mylib.myfun()

आप इस तरह के कार्यों और वर्गों को भी आयात कर सकते हैं:

from anything.mylib import MyClass
from anything.mylib import myfun

instance = MyClass()
result = myfun()

आपके द्वारा अपने अंदर जगह लेने वाला कोई भी चर समारोह या कक्षा __init__.pyतक पहुँचा जा सकता है:

import anything

print(anything.myvar)

या इस तरह:

from anything import myvar

print(myvar)

मेरे फ़ोल्डर संरचना है utils\__init__.pyऔर utils\myfile.py। (यूटिल्स में दोनों फाइलें हैं) यह मैं आयात करने की कोशिश कर रहा हूं from utils.myfile import myMethod। लेकिन मुझे मिलता है ModuleNotFoundError: No module named 'utils'। क्या गलत हो सकता है? पुनश्च: मैं उपयोग कर रहा हूं Djangoऔर आयात करने की कोशिश कर रहा हूं , views.pyजो utilsफ़ोल्डर के समान स्तर पर है
जागृति

यह जब मॉड्यूल आयात करने निरपेक्ष पथ का उपयोग करें और के साथ अपने कार्यक्रम चलाने के लिए संभव हैPYTHONPATH=. python path/to/program.py
Nurettin

21

क्या आपकी कामगार निर्देशिका में कोई __init__.pyफ़ाइल है?

__init__.pyयदि निर्देशिका एक मॉड्यूल है, तो यह निर्धारित करने के लिए पायथन का उपयोग करता है।


16

कोशिश करो import .lib.BoxTimeपीईपी 328 में सापेक्ष आयात के बारे में अधिक जानकारी के लिए पढ़ें ।


2
मुझे नहीं लगता कि मैंने पहले कभी देखा है कि वाक्यविन्यास का उपयोग किया जाता है। क्या इस पद्धति का उपयोग करने के लिए मजबूत कारण (नहीं) है?
18

2
इसका जवाब क्यों नहीं था। ज़रूर, अगर आप पूरे पैकेज की बात करना चाहते हैं, तो आपको ऐसा करना चाहिए। लेकिन मूल प्रश्न यह नहीं था।
ट्रैविस ग्रिग्स

यह मुझे देता है: ValueError: गैर-पैकेज में सापेक्ष आयात का प्रयास किया गया
एलेक्स

5
यह केवल तभी काम करता है जब आप जिस फ़ाइल से आयात कर रहे हैं वह स्वयं एक पैकेज का हिस्सा है। यदि नहीं, तो आपको वह त्रुटि प्राप्त होगी जो @ एलेक्स ने बताई है।
जोनाथन रेनहार्ट

8

मैं ऐसा करता हूं जो मूल रूप से सभी मामलों को कवर करता है (सुनिश्चित करें कि आपके पास __init__.pyरिश्तेदार / पथ / से / आपके / परिवाद / फ़ोल्डर में है):

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/relative/path/to/your/lib/folder")
import someFileNameWhichIsInTheFolder
...
somefile.foo()


उदाहरण:
आपके प्रोजेक्ट फ़ोल्डर में है:

/root/myproject/app.py

आपके पास किसी अन्य प्रोजेक्ट फ़ोल्डर में है:

/root/anotherproject/utils.py
/root/anotherproject/__init__.py

आप /root/anotherproject/utils.pyफू फ़ंक्शन का उपयोग और कॉल करना चाहते हैं जो इसमें है।

तो आप app.py में लिखो:

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/../anotherproject")
import utils

utils.foo()

2
यदि आप उपयोग कर रहे हैं, तो आप os.pathशायद os.path.join((os.path.dirname(os.path.realpath(__file__)),'..','anotherproject')अपने पथ समागम में '/' को हार्डकोड करने के बजाय उपयोग करना चाहते हैं ।
काऊबर्ट

तुम बस के "../anotherproject"बिना क्यों नहीं कर सकते os.path.dirname()?
मोशे रबाएव

@MosheRabaev - os.path फ़ंक्शन का उपयोग करना अच्छा अभ्यास है। "../Anotherproject" लिखने और विंडोज ओएस पर कोड को स्थानांतरित करने के मामले में, कोड टूट जाएगा! OS.path यूटल्स जानता है कि OS पर चल रहे कोड पर विचार करके सही रास्ता कैसे लौटाएं। अधिक जानकारी के लिए docs.python.org/2/library/os.path.html
बुध

@MosheRabaev और यदि आप बिना ".." का उपयोग करते हैं dirname(realpath(__file__)), तो यह आपकी वर्तमान कार्यशील निर्देशिका के सापेक्ष पथ की गणना करेगा, जब आप स्क्रिप्ट चलाते हैं, न कि उस लिपि के सापेक्ष जहां आप रहते हैं।
टीजे एलिस

5

__init__.pyउपनिर्देशिका / देयता में एक खाली फ़ाइल बनाएँ । और मुख्य कोड की शुरुआत में जोड़ें

from __future__ import absolute_import 

फिर

import lib.BoxTime as BT
...
BT.bt_function()

या और अच्छा

from lib.BoxTime import bt_function
...
bt_function()

0

इन जवाबों के लिए बस एक अतिरिक्त।

यदि आप सभी उपनिर्देशिकाओं से सभी फ़ाइलों को आयात करना चाहते हैं , तो आप इसे अपनी फ़ाइल की जड़ में जोड़ सकते हैं।

import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])

और फिर आप बस उपनिर्देशिकाओं से फ़ाइलों को आयात कर सकते हैं जैसे कि ये फाइलें वर्तमान निर्देशिका के अंदर हैं।

काम करने का उदाहरण

यदि मेरे पास मेरी परियोजना में उपनिर्देशिका के साथ निम्नलिखित निर्देशिका है ...

.
├── a.py
├── b.py
├── c.py
├── subdirectory_a
   ├── d.py
   └── e.py
├── subdirectory_b
   └── f.py
├── subdirectory_c
   └── g.py
└── subdirectory_d
    └── h.py

मैं अपनी a.pyफ़ाइल के अंदर निम्नलिखित कोड डाल सकता हूं

import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])

# And then you can import files just as if these files are inside the current directory

import b
import c
import d
import e
import f
import g
import h

दूसरे शब्दों में, यह कोड सार करेगा कि फाइल किस निर्देशिका से आ रही है।


-1

/project/tester.py

/project/lib/BoxTime.py

__init__.pyजब तक आप फ़ाइल तक नहीं पहुंचते तब तक लाइन के नीचे खाली फ़ाइल बनाएँ

/project/lib/somefolder/BoxTime.py

#lib- जरूरतों में दो आइटम एक होते हैं __init__.pyऔर एक डायरेक्टरी जिसका नाम somefolder होता #somefolderहै, दो आइटम होते हैं boxtime.pyऔर__init__.py


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