একটি উপ ডিরেক্টরি থেকে একটি ফাইল আমদানি করবেন?


455

আমার কাছে একটি ফাইল রয়েছে 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
হ্যাক লাগছে কেন ? এটি অজগরটি নিরাপদ / উপলভ্য আমদানি ডিরেক্টরিগুলি চিহ্নিত করে।
আইএবস্ট্র্যাক্ট

7
এটি কেবল নিরাপদ / উপলভ্য আমদানি ডিরেক্টরিগুলি চিহ্নিত করে না, তবে ডিরেক্টরিটির নাম আমদানি করার সময় কিছু সূচনা কোড চালানোর একটি উপায়ও সরবরাহ করে।
সাদজাদ

32
হ্যাঁ এটি হ্যাকি এবং এমনকি নোংরা এবং আমার মতে ভাষাটিকে ফাইল সিস্টেমের মধ্যে ফাইল লোড করার উপায়টি চাপানো উচিত নয়। পিএইচপি-তে আমরা ব্যবহারকারীর কোডটি একাধিক অটলয়েডিং ফাংশনগুলি নিবন্ধভুক্ত করে সমস্যা সমাধান করেছি যখন নামস্থান / শ্রেণি অনুপস্থিত থাকে solved তারপরে সম্প্রদায়টি পিএসআর -4 স্ট্যান্ডার্ড তৈরি করেছে এবং সুরকার এটি প্রয়োগ করে এবং আজকাল কাউকেই এটি নিয়ে মাথা ঘামানোর দরকার নেই। আর মূঢ় হার্ডকোডেড __init__ফাইল (কিন্তু আপনি তা, শুধু একটি autoloading হুক রেজিস্টার করো চাই! এই মধ্যে পার্থক্য হল hacky এবং hackable )।
মরগান টোভেরি কুইলিং

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
আসুন সেই লিঙ্কটিকে ক্লিকযোগ্য করে তুলুন
গ্যাব্রিয়েল স্ট্যাপলস

একটি প্যাকেজ বাস্তবায়নের জন্য দুর্দান্ত lib
ওয়াকথ্রো

দয়া করে নোট করুন: সাবডিয়ারগুলিতে ড্যাশ বা বিন্দু থাকবে না, তবে আন্ডারস্কোরগুলি বৈধ। আমার জন্য যা অন্য চিহ্নের নামের মতো একই বিধিনিষেধের মতো মনে হয়, তবে আমি এখনও এটি ডকুমেন্টেশন স্তরে খনন করি নি।
আলেকজান্ডার স্টোহর

আন্ডারস্কোর => অজগর 3 (মন্তব্য সম্পাদনা করার জন্য দেরী)
আলেকজান্ডার স্টোহর

68

আপনি এটি inোকানোর চেষ্টা করতে পারেন sys.path:

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

11
এটি দুর্দান্ত যদি আপনি কোনও কারণে init .py ফাইল তৈরি করতে না পারেন বা তৈরি করেন না ।
jpihl

1
আপনি যদি "প্রকল্প" ডিরেক্টরি থেকে অজগর চালনা করেন এটি কাজ করে। দ্য "." আপনার বর্তমান কার্যনির্বাহী ডিরেক্টরিটির সাথে সম্পর্কিত বলে ব্যাখ্যা করা হয়, আপনি যে ফাইলটি সম্পাদন করছেন সেই ফাইলের সাথে তুলনামূলক নয়। আপনি বলে দিন cd /data, python ../project/tester.py। তাহলে এটি কাজ করবে না।
সকাল

2
এটি আমার পক্ষে কাজ করেছে। আমি এটি একটি init .py ফাইলের চেয়ে বেশি পছন্দ করি , এটি ক্লিনার আমদানির বিবৃতি দেয়।
টেলর ইভানসন

5
এটি অনেক বেশি কাজ করে এবং এটি "সঠিক" সমাধান। init .py বোটোর মতো প্যাকেজগুলিকে মিস্ করে যা মডিউলগুলির সাথে তাদের নিজস্ব শিশু ফোল্ডার রয়েছে।
ডেভ ডপসন

1
@jpihl আপনাকে folderinit__.py নামে একটি ফাঁকা ফাইল তৈরি করতে হবে allow ফোল্ডারটি থেকে পাইথন আমদানি মডিউলগুলির অনুমতি দিতে। আমি সেই সমাধানটি চেষ্টা করেছি এবং পুরোপুরি কাজ করে (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
পরোক্ষ

21

আপনার lib ডিরেক্টরিতে একটি __init__.pyফাইল রয়েছে?

পাইথন __init__.pyএকটি ডিরেক্টরি মডিউল কিনা তা নির্ধারণ করতে ব্যবহার করে।


16

ব্যবহার করে দেখুন import .lib.BoxTime। আরও তথ্যের জন্য পিইপি 328 এ আপেক্ষিক আমদানি সম্পর্কে পড়ুন ।


2
আমি মনে করি না যে আমি আগে কখনও সিনট্যাক্স ব্যবহার করেছি। এই পদ্ধতিটি ব্যবহার করার কোনও শক্ত কারণ আছে (না)?
tgray

2
কেন এই উত্তর ছিল না। অবশ্যই, আপনি যদি পুরো প্যাকেজগুলি করতে চান তবে আপনার এটি করা উচিত। তবে মূল প্রশ্নটি এটাই ছিল না।
ট্র্যাভিস গ্রিগস 17

এটি আমাকে দেয়: ভ্যালু এরির: নন-প্যাকেজে আপেক্ষিক আমদানির চেষ্টা করা হয়েছে
অ্যালেক্স

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()?
মোশে রাবায়েভ

@ মোশেরবায়েভ - os.path ফাংশন ব্যবহার করা ভাল অনুশীলন। "../Anotherproject" রিট করার ক্ষেত্রে এবং কোডটি উইন্ডোজ ওএসে সরানোর ক্ষেত্রে কোডটি ভেঙে যাবে! OS.path ইউএসগুলি কীভাবে ওএস কোডটি চলছে তা বিবেচনা করে সঠিক পথে ফিরতে জানে। আরও তথ্যের জন্য docs.python.org/2/library/os.path.html
বুধ

@ মোশেরবায়েভ এবং যদি আপনি ".." ব্যবহার dirname(realpath(__file__))করে থাকেন তবে স্ক্রিপ্টটি যেখানে চালিত হবে তার তুলনায় নয়, যখন আপনি স্ক্রিপ্টটি চালাবেন তখন এটি আপনার বর্তমান কার্যনির্বাহী ডিরেক্টরি সম্পর্কিত পাথটি গণনা করবে।
টিজে এলিস

5

__init__.pyউপ-ডিরেক্টরি / lib এ একটি খালি ফাইল তৈরি করুন । এবং প্রধান কোডের শুরুতে যুক্ত করুন

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দুটি আইটেম রয়েছে boxtime.pyএবং__init__.py


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.