পাইথন অনুসন্ধানের পথটি অন্য উত্সে প্রসারিত করুন


106

আমি সবেমাত্র একটি বৃহত্তর বিদ্যমান কোড বেস সহ একটি প্রকল্পে যোগদান করেছি। আমরা লিনাক্সে বিকাশ করি এবং ব্যবহার এবং আইডিই করি না। আমরা কমান্ড লাইনের মধ্য দিয়ে চলি। আমি যখন প্রকল্পের মডিউলগুলি চালাচ্ছি তখন কীভাবে পাইথনটি সঠিক পথটি সন্ধান করতে হবে তা নির্ধারণ করার চেষ্টা করছি। উদাহরণস্বরূপ, যখন আমি এই জাতীয় কিছু চালাই:

python someprojectfile.py

আমি পাই

ImportError: no module named core.'somemodule'

আমি আমার সমস্ত আমদানির জন্য এটি পেয়েছি এটি ধরে নিয়েছি এটি পথের সাথে একটি সমস্যা।

TLDR:

আমি কীভাবে পাইথন অনুসন্ধান করব ~/codez/project/এবং ইমপোর্ট স্টেটমেন্টের সময় * .py ফাইলের জন্য সমস্ত ফাইল এবং ফোল্ডার পেতে পারি ।

উত্তর:


171

এটি করার কয়েকটি সম্ভাব্য উপায় রয়েছে:

  • PYTHONPATHআমদানি করা মডিউলগুলি অনুসন্ধান করার জন্য পরিবেশের পরিবর্তনশীল ডিরেক্টরিগুলির একটি কোলন-বিচ্ছিন্ন তালিকায় সেট করুন ।
  • আপনার প্রোগ্রামে sys.path.append('/path/to/search')পাইথন যে ডিরেক্টরিগুলির আমদানি করা মডিউলগুলি সন্ধান করতে চান তার নাম যুক্ত করতে ব্যবহার করুন। sys.pathপাইথন প্রতিবার মডিউলটি আমদানি করতে বলা হয়ে থাকে কেবল সেই ডিরেক্টরিগুলির তালিকা এবং আপনি এটি প্রয়োজনীয় হিসাবে এটি পরিবর্তন করতে পারেন (যদিও আমি স্ট্যান্ডার্ড ডিরেক্টরিগুলির কোনও অপসারণের প্রস্তাব দিই না!)। পাইথন শুরু হওয়ার সাথে সাথে আপনি পরিবেশের পরিবর্তনশীলগুলিতে যে কোনও ডিরেক্টরি রেখেছিলেন PYTHONPATHতা sys.pathsertedোকানো হবে।
  • site.addsitedirডিরেক্টরিতে যুক্ত করতে ব্যবহার করুন sys.path। এই এবং কেবল সরল সংযোজনের মধ্যে পার্থক্য হ'ল আপনি যখন ব্যবহার করবেন তখন addsitedirএটি .pthসেই ডিরেক্টরিতে sys.pathথাকা ফাইলগুলিও সন্ধান করে এবং ফাইলগুলির সামগ্রীর উপর ভিত্তি করে অতিরিক্ত ডিরেক্টরি যুক্ত করার জন্য এগুলি ব্যবহার করে । আরও বিশদ জন্য ডকুমেন্টেশন দেখুন।

এর মধ্যে কোনটি আপনি ব্যবহার করতে চান তা আপনার পরিস্থিতির উপর নির্ভর করে। মনে রাখবেন যে আপনি যখন অন্য প্রকল্পে আপনার প্রকল্পটি বিতরণ করেন, তারা সাধারণত এটি এমনভাবে ইনস্টল করেন যে পাইথন কোড ফাইলগুলি পাইথনের আমদানিকারক দ্বারা স্বয়ংক্রিয়ভাবে সনাক্ত হয়ে যায় (অর্থাত প্যাকেজগুলি সাধারণত site-packagesডিরেক্টরিতে ইনস্টল করা থাকে ), সুতরাং যদি আপনি sys.pathআপনার কোডের সাথে ঝামেলা করেন , এটি অপ্রয়োজনীয় হতে পারে এবং সেই কোডটি অন্য কম্পিউটারে চালিত হওয়ার পরে এটির বিরূপ প্রভাবও পড়তে পারে। বিকাশের জন্য, আমি একটি অনুমান করতে চাই যে PYTHONPATHসাধারণত সেটিংসই সর্বোত্তম উপায়।

তবে, যখন আপনি এমন কিছু ব্যবহার করছেন যা কেবলমাত্র আপনার নিজের কম্পিউটারে চালিত হয় (বা যখন আপনি নন-স্ট্যান্ডার্ড সেটআপগুলি থাকে, যেমনঃ কখনও কখনও ওয়েব অ্যাপ্লিকেশনের ফ্রেমওয়ার্কগুলিতে) তখন এমন কিছু করা সম্পূর্ণ অস্বাভাবিক নয় not

import sys
from os.path import dirname
sys.path.append(dirname(__file__))

সুতরাং আমি যদি 15 টি উপ-ডিরেক্টরিগুলি বলতে চাই, তবে আমাকে পৃথকভাবে প্রতিটি যুক্ত করতে হবে?
থিমেস্ট্রো

এবং আপনি পাইথনপথ পরিবর্তন করতে কোনও কমান্ড লাইন যুক্তির উদাহরণ দিতে পারেন?
থিমেস্ট্রো

3
সেট করতে PYTHONPATH: .bashrcআপনার শেল যে কোনও স্টার্টআপ ফাইল ব্যবহার করে (যদি এটি বাশ না হয়), লিখুন export PYTHONPATH=$PYTHONPATH:$HOME/codez/project। তবে আপনার কাছে যদি উপ-ডিরেক্টরিগুলির একগুচ্ছ থাকে তবে আমি একটি .pthফাইল তৈরি করে ব্যবহার করব site.addsitedir। আপনি এমন একটি মডিউল তৈরি করতে পারেন sitecustomizeযা আপনার জন্য ফাংশনটি কল করতে পারে; এটিকে রাখার চেষ্টা করুন ~/.local/lib/python2.6/sitecustomize.py(আপনার পাইথন সংস্করণটির বিকল্প দিন) যাতে এটি আশা করা যায় যে স্বয়ংক্রিয়ভাবে আমদানি হয়ে যায়।
ডেভিড জেড

আমি আমার .bashrc ফাইলে নিম্নলিখিতটি রেখেছি এবং সেই আমদানিগুলির সাথে আমার এখনও ভাগ্য নেই। কোন ধারনা? আমি কীভাবে একটি। Pth ফাইল তৈরি করব? পাইথনপাথ = $ পাইথনপাথ: OME হোম / অ্যাডাইফটিস / কোডজ / এক্সপোর্ট পাইথোনপাথ = $ পাইথনপথ: OME হোম / অ্যাডাইফটিস / কোডজ / প্রজেক্ট এক্সপোর্ট পাইথনপাথ = Y পাইথনপ্যাট / কোড / এক্সটেনটিপথ / কোড / কোর / কোড হোম / অ্যাডাইফটিস / কোডজ / প্রজেক্ট / প্রক্সি এক্সপোর্ট পাইথোনপাথ = $ পাইথনপাথ: OME হোম / অ্যাডাইফোটিস / কোডজ / প্রজেক্ট /
কনফ

একটি টার্মিনাল খুলুন এবং চালনার চেষ্টা echo $PYTHONPATH। যদি পরিবেশের ভেরিয়েবলটি সঠিকভাবে সেট করা থাকে তবে আপনার উচিত একটি ডিরেক্টরি থেকে কোলন-বিচ্ছিন্ন তালিকা। .pthফাইল সম্পর্কে তথ্যের জন্য, siteআমি আমার উত্তরে যে মডিউলটি সংযুক্ত করেছি তার জন্য ডকুমেন্টেশন দেখুন । এটি আপনাকে কী কী বিষয়বস্তু হওয়া উচিত এবং কীভাবে সেগুলি ব্যবহার করবে তা আপনাকে জানায়।
ডেভিড জেড

13

আপনার এখানে পাইথন প্যাকেজগুলি পড়তে হবে: http://docs.python.org/tutorial/modules.html

আপনার উদাহরণ থেকে, আমি অনুমান করব যে আপনার কাছে সত্যিই একটি প্যাকেজ রয়েছে ~/codez/project__init__.pyপাইথন ডিরেক্টরিতে থাকা ফাইলটি একটি ডিরেক্টরিকে একটি নেমস্পেসে ম্যাপ করে। যদি আপনার সাব-ডাইরেক্টরিগুলিতে সমস্ত __init__.pyফাইল থাকে তবে আপনাকে কেবল নিজের ডিরেক্টরিতে বেস ডিরেক্টরি যুক্ত করতে হবে PYTHONPATH। উদাহরণ স্বরূপ:

কোনো PYTHONPATH = $ কোনো PYTHONPATH: $ হোম / adaifotis / প্রকল্প

আপনার পাইথনপথ পরিবেশের পরিবর্তনশীল পরীক্ষা করার সাথে সাথে ডেভিড ব্যাখ্যা করেছেন, আপনি अजথায় এটি পরীক্ষা করতে পারেন:

$ python
>>> import project                      # should work if PYTHONPATH set
>>> import sys
>>> for line in sys.path: print line    # print current python path

...


আপনি আপনার __init__.pyব্যাকটিক্স রাখতে চান এটি স্পষ্ট করতে আপনার সত্যিকারের __init__.pyবিপরীতে, আপনি কী বোঝাতে চাইছেন init.py। শুধু বিভ্রান্তি newbies এড়ানোর জন্য। :)
antred

4

আমি জানি এই থ্রেডটি কিছুটা পুরানো, তবে এটির হৃদয় পেতে আমার কিছুটা সময় লেগেছে, তাই আমি ভাগ করে নিতে চাই।

আমার প্রকল্পে, আমার প্যারেন্ট ডিরেক্টরিতে মূল স্ক্রিপ্ট ছিল এবং মডিউলগুলি আলাদা করার জন্য, আমি সমস্ত মডিউলগুলি "মডিউল" নামে একটি সাব-ফোল্ডারে রেখেছি। আমার মূল স্ক্রিপ্টে, আমি এইগুলি এই জাতীয় মডিউলগুলি আমদানি করি (রিপোর্ট.পি নামে পরিচিত মডিউলটির জন্য):

from modules.report import report, reportError

যদি আমি আমার মূল স্ক্রিপ্ট কল করি, এটি কাজ করে। তবুও, আমি প্রতিটি মডিউল পরীক্ষার জন্য প্রত্যেকটিতে একটি অন্তর্ভুক্ত করে main()এবং প্রত্যেকে সরাসরি কল করে দেখতে চেয়েছিলাম :

python modules/report.py

পাইথন এখন অভিযোগ করেছে যে এটি "মডিউল নামে পরিচিত একটি মডিউল" খুঁজে পাচ্ছে না। এখানে মূল কীটি হ'ল ডিফল্টরূপে পাইথন স্ক্রিপ্টটির ফোল্ডারটিকে তার অনুসন্ধানের পথে অন্তর্ভুক্ত করে, তবে সিডাব্লুডি নয় NOT সুতরাং এই ত্রুটিটি যা বলেছে তা হ'ল "আমি কোনও মডিউল সাবফোল্ডার খুঁজে পাচ্ছি না"। কারণ रिपोर्ट.পি মডিউলটি যে ডিরেক্টরি থেকে থাকে সেখানে ডিরেক্টরি থেকে কোনও "মডিউল" উপ-ডিরেক্টরি নেই।

আমি দেখতে পাচ্ছি যে এর নিকটতম সমাধানটি পাইথন অনুসন্ধানের পথে সিডাব্লুডিটিকে শীর্ষে অন্তর্ভুক্ত করে যুক্ত করা:

import sys

sys.path.append(".")

পাইথন সিডাব্লুডি (বর্তমান ডিরেক্টরি) অনুসন্ধান করে, "মডিউল" সাব-ফোল্ডারটি সন্ধান করে এবং সবকিছু ঠিক আছে।


3

আমি এই উত্তরটি খুঁজছি এবং এইগুলির কোনওটি পছন্দ করি না read

তাই আমি একটি দ্রুত এবং নোংরা সমাধান লিখেছি। এটি কেবলমাত্র আপনার সিএস.পথের উপরে রাখুন এবং এটি folder(বর্তমান ওয়ার্কিং ডিরেক্টরি থেকে) বা এর অধীনে যে কোনও ডিরেক্টরি যুক্ত করবে abspath:

#using.py

import sys, os.path

def all_from(folder='', abspath=None):
    """add all dirs under `folder` to sys.path if any .py files are found.
    Use an abspath if you'd rather do it that way.

    Uses the current working directory as the location of using.py. 
    Keep in mind that os.walk goes *all the way* down the directory tree.
    With that, try not to use this on something too close to '/'

    """
    add = set(sys.path)
    if abspath is None:
        cwd = os.path.abspath(os.path.curdir)
        abspath = os.path.join(cwd, folder)
    for root, dirs, files in os.walk(abspath):
        for f in files:
            if f[-3:] in '.py':
                add.add(root)
                break
    for i in add: sys.path.append(i)

>>> import using, sys, pprint
>>> using.all_from('py') #if in ~, /home/user/py/
>>> pprint.pprint(sys.path)
[
#that was easy
]

এবং আমি এটি পছন্দ করি কারণ আমার কিছু এলোমেলো সরঞ্জামগুলির জন্য একটি ফোল্ডার থাকতে পারে এবং সেগুলি প্যাকেজ বা কোনও কিছুর অংশ না হয়ে থাকতে পারে এবং এখনও কয়েকটি কোডের কয়েকটি লাইনে তাদের কয়েকটি (বা সমস্ত) অ্যাক্সেস পেতে পারি।


3

আমার সর্বাধিক সহজ উপায় হ'ল একটি ফাইল "any_name.pth" তৈরি করা এবং এটি আপনার ফোল্ডারে "\ Lib \ সাইট-প্যাকেজগুলি" এ রাখা। পাইথন ইনস্টল করা আছে সেখানে আপনার সেই ফোল্ডারটি খুঁজে পাওয়া উচিত।

সেই ফাইলটিতে আপনি যে ডিরেক্টরিগুলির আমদানির জন্য মডিউল রাখতে চান সেখানে একটি তালিকা রাখুন। উদাহরণস্বরূপ, এই ফাইলটিতে একটি লাইন তৈরি করুন:

সি: \ ব্যবহারকারী \ উদাহরণ ... \ উদাহরণ

অজগরটি চালিয়ে আপনি এটি কাজ করে তা বলতে সক্ষম হবেন:

import sys
for line in sys: print line

আপনি যেখান থেকে আমদানি করতে পারবেন সেগুলির মধ্যে আপনি নিজের ডিরেক্টরি মুদ্রিত দেখতে পাবেন। এখন আপনি একটি "mymodule.py" ফাইলটি আমদানি করতে পারেন যা সেই ডিরেক্টরিতে যতটা সহজে বসবে:

import mymodule

এটি সাবফোল্ডারগুলি আমদানি করবে না। এর জন্য আপনি কল্পনা করতে পারেন যে আপনি নির্ধারিত ফোল্ডারের সমস্ত সাব ফোল্ডার সমন্বিত একটি .pth ফাইল তৈরি করতে পাইথন স্ক্রিপ্ট তৈরি করতে পারেন। এটি সম্ভবত শুরুতে চালানো আছে।


0

পুরানো প্রশ্নের নতুন বিকল্প ডেবিয়ানে প্যাকেজ
ইনস্টল করা fail2banদেখে মনে হচ্ছে /usr/lib/python3/dist-packages/fail2banপাইথন 3 এ নয় এমন কোনও পথে ইনস্টল করা হার্ডকোডযুক্ত sys.path


> python3
Python 3.7.3 (v3.7.3:ef4ec6ed12, Jun 25 2019, 18:51:50)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', '/usr/lib/python37.zip', '/usr/lib/python3.7', '/usr/lib/python3.7/lib-dynload', '/usr/lib/python3.7/site-packages']
>>>

সুতরাং, কেবল অনুলিপি করার পরিবর্তে, আমি (বাশ) লাইব্রেরিকে আরও নতুন সংস্করণে লিঙ্ক করেছি।
মূল অ্যাপ্লিকেশনটিতে ভবিষ্যতের আপডেটগুলি সংযুক্ত সংস্করণগুলিতে স্বয়ংক্রিয়ভাবে প্রয়োগ করা হবে।

 if [ -d /usr/lib/python3/dist-packages/fail2ban ]
   then
      for d in /usr/lib/python3.*
      do
         [ -d ${d}/fail2ban ] || \
            ln -vs /usr/lib/python3/dist-packages/fail2ban ${d}/
      done
   fi
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.