পাইথন: বর্তমান চলমান স্ক্রিপ্টের তুলনায় sys.path যুক্ত করার সর্বোত্তম উপায়


103

আমার স্ক্রিপ্টে পূর্ণ একটি ডিরেক্টরি রয়েছে (আসুন আমরা বলি project/bin)। আমার কাছে একটি লাইব্রেরিও রয়েছে project/libএবং স্ক্রিপ্টগুলি এটি স্বয়ংক্রিয়ভাবে লোড হওয়া চাই। আমি সাধারণত প্রতিটি স্ক্রিপ্টের শীর্ষে এটি ব্যবহার করি:

#!/usr/bin/python
from os.path import dirname, realpath, sep, pardir
import sys
sys.path.append(dirname(realpath(__file__)) + sep + pardir + sep + "lib")

# ... now the real code
import mylib

এটি এক ধরণের জটিল, কুরুচিপূর্ণ এবং প্রতিটি ফাইলের শুরুতে আটকানো হয়। এই কাজ করতে একটি ভাল উপায় আছে কি?

সত্যিই আমি যা আশা করি তা হ'ল এর মতো মসৃণ কিছু:

#!/usr/bin/python
import sys.path
from os.path import pardir, sep
sys.path.append_relative(pardir + sep + "lib")

import mylib

বা আরও ভাল, যখন আমার সম্পাদক (বা অন্য কেউ অ্যাক্সেস করেছেন) তার ক্লিন আপ প্রক্রিয়ার অংশ হিসাবে আমদানিগুলি পুনরায় অর্ডার করার সিদ্ধান্ত নেন তখন এমন কিছু ভেঙে যাবে না:

#!/usr/bin/python --relpath_append ../lib
import mylib

এটি সরাসরি নন-পিক্সিক প্ল্যাটফর্মগুলিতে পোর্ট করবে না, তবে এটি জিনিস পরিষ্কার রাখবে।


4
আরও দেখুন: stackoverflow.com/questions/2349991/...
dreftymac

উত্তর:


25

আপনি যদি প্রতিটি ফাইল সম্পাদনা করতে চান না

  • আপনার একটি সাধারণ অজগর লাইব্রেরির মতো লাইব্রেরি ইনস্টল করুন
    বা
  • PYTHONPATHআপনার সেট করুনlib

অথবা আপনি যদি প্রতিটি ফাইলে একটি লাইন যুক্ত করতে ইচ্ছুক থাকেন তবে উপরে আমদানি বিবৃতি যুক্ত করুন

import import_my_lib

রাখা import_my_lib.pyবিন এবং import_my_libসঠিকভাবে যাই হোক না কেন পাইথন পথ সেট করতে পারেন libযদি আপনি চান


120

এটি আমি ব্যবহার করি:

import os, sys
sys.path.append(os.path.join(os.path.dirname(__file__), "lib"))

4
আমি sys.path.insert (0, ..) করব যাতে এটি অন্য পাথের দ্বারা ওভাররাইড না হয়।
জন জিয়াং

এটি স্বয়ংক্রিয়ভাবে চালানোর কোনও উপায় নেই?
ডেনিস ডি বার্নার্ডি

4
এটি কিছুটা ঝুঁকিপূর্ণ। যদি __file__বর্তমান শ্রমিক ডিরেক্টরিতে অবশ্যই এমন একটি আপেক্ষিক ফাইলের নাম আপেক্ষিক (যেমন, setup.py), তারপর os.path.dirname(__file__)হবে খালি স্ট্রিং। এই এবং জন্য অনুরূপ উদ্বেগ জন জিয়াং দ্বারা উত্থাপিত , ekhumoro 's আরও সাধারণ উদ্দেশ্য সমাধান জোরালোভাবে বাঞ্ছনীয়।
সিসিল কারি

31

আমি ব্যাবহার করছি:

import sys,os
sys.path.append(os.getcwd())

4
আমি প্রায়শই করিsys.path.append('.')
কিম্বো

4
স্ক্রিপ্টটি যদি কোনও ভিন্ন ডিরেক্টরি থেকে চালিত হয় তবে কী হবে? উদাহরণস্বরূপ সম্পূর্ণ সিস্টেমের পাথ দিয়ে রুট ডিরেক্টরি থেকে? তারপরে os.getcwd () "/" ফিরিয়ে দেবে
ওবায়হান

4
এটি কখনও করবেন না। বর্তমান ওয়ার্কিং ডিরেক্টরি (সিডব্লিউডি) আপনি যা ভাবেন তা নিশ্চিত হওয়ার গ্যারান্টিযুক্ত নয় - বিশেষত অপ্রবর্তনীয় প্রান্তের ক্ষেত্রে অবশ্যই আপনার অবশ্যই এক মাইল দূরে আসতে দেখা উচিত ছিল। __file__পরিবর্তে অন্য অর্ধ-বুদ্ধিমান বিকাশকারীদের মতো কেবল উল্লেখ
সিসিল কারি

15

একটি মোড়ক মডিউল তৈরি করুন project/bin/lib, এতে এটি রয়েছে:

import sys, os

sys.path.insert(0, os.path.join(
    os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'lib'))

import mylib

del sys.path[0], sys, os

তারপরে আপনি আপনার স্ক্রিপ্টগুলির শীর্ষে থাকা সমস্ত ক্রাফ্টটি এর সাথে প্রতিস্থাপন করতে পারেন:

#!/usr/bin/python
from lib import mylib

9

আপনি যদি কোনওভাবেই স্ক্রিপ্টের সামগ্রী পরিবর্তন করতে না চান তবে বর্তমান কার্যনির্বাহী ডিরেক্টরিটি .$ পাইথনপথে ( পূর্বে উদাহরণ দেখুন) এঁকে দিন

PYTHONPATH=.:$PYTHONPATH alembic revision --autogenerate -m "First revision"

এবং এটি একটি দিন কল!


docs.python.org/3/tutorial/modules.html#the-module-search-path বলেছেন: "sys.path এই অবস্থানগুলি থেকে আরম্ভ করা হয়েছে: ইনপুট স্ক্রিপ্টযুক্ত ডিরেক্টরি"। আমি মনে করি এটি সত্য নয়।

আমি এটি করার প্রবণতা করছি, বিশেষত .envrc এ যাতে ডার্নিভের সাথে এটি এমনকি স্বয়ংক্রিয় এবং বিচ্ছিন্নও।
এডওয়ার্ড এম

8

সিএক্স_ফ্রিজে ব্যবহার বা আইডিএল ব্যবহার ব্যতীত পাইথন ৩.৪
++ ব্যবহার করা। 😃

import sys
from pathlib import Path

sys.path.append(Path(__file__).parent / "lib")

পাইথন 2 সামঞ্জস্যপূর্ণ: আমদানি করুন পাথলিব আমদানি s sys.path.append (os.path.dirname ( ফাইল ))
মাইকেল

6

আপনি python -mপ্রাসঙ্গিক মূল ডিয়ার থেকে স্ক্রিপ্টটি চালাতে পারেন । এবং "মডিউলগুলি" আর্গুমেন্ট হিসাবে পাস করুন।

উদাহরণ: $ python -m module.sub_module.main # Notice there is no '.py' at the end.


আরেকটি উদাহরণ:

$ tree  # Given this file structure
.
├── bar
│   ├── __init__.py
│   └── mod.py
└── foo
    ├── __init__.py
    └── main.py

$ cat foo/main.py
from bar.mod import print1
print1()

$ cat bar/mod.py
def print1():
    print('In bar/mod.py')

$ python foo/main.py  # This gives an error
Traceback (most recent call last):
  File "foo/main.py", line 1, in <module>
    from bar.mod import print1
ImportError: No module named bar.mod

$ python -m foo.main  # But this succeeds
In bar/mod.py

4
এম সুইচটি ব্যবহার করা
এটির

4

প্রদত্ত প্রতিটি উত্তরের সাথে একটি সমস্যা রয়েছে যা সংক্ষিপ্ত করে বলা যেতে পারে "আপনার স্ক্রিপ্টের শুরুতে এই জাদুকরী উদ্দীপনাটি যুক্ত করুন just কোডের কেবল একটি লাইন বা দুটি দিয়ে আপনি কী করতে পারেন দেখুন"। তারা প্রতিটি সম্ভাব্য পরিস্থিতিতে কাজ করবে না!

উদাহরণস্বরূপ, এই জাতীয় একটি যাদুকরী জ্বলন ফাইল ব্যবহার করে । দুর্ভাগ্যক্রমে, আপনি যদি cx_Freeze ব্যবহার করে আপনার স্ক্রিপ্টটি প্যাকেজ করেন বা আপনি IDLE ব্যবহার করছেন তবে এর ব্যতিক্রম ঘটবে।

এই জাতীয় আরও একটি যাদু জাগ্রত os.getcwd () ব্যবহার করে। এটি কেবলমাত্র তখনই কাজ করবে যখন আপনি কমান্ড প্রম্পট থেকে আপনার স্ক্রিপ্টটি চালাচ্ছেন এবং আপনার স্ক্রিপ্টযুক্ত ডিরেক্টরিটি বর্তমান ওয়ার্কিং ডিরেক্টরি (এটি আপনি স্ক্রিপ্ট চালানোর আগে ডিরেক্টরিতে পরিবর্তনের জন্য সিডি কমান্ডটি ব্যবহার করেছেন)। Godsশ্বর! আমি আশা করি আপনার পাইথন লিপিটি কোথাও PATH এ থাকলে এটি কেন কাজ করবে না তা ব্যাখ্যা করার দরকার নেই এবং আপনি কেবল আপনার স্ক্রিপ্ট ফাইলটির নাম লিখে এটি চালিয়েছিলেন।

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

import inspect
import os
import sys

# Add script directory to sys.path.
# This is complicated due to the fact that __file__ is not always defined.

def GetScriptDirectory():
    if hasattr(GetScriptDirectory, "dir"):
        return GetScriptDirectory.dir
    module_path = ""
    try:
        # The easy way. Just use __file__.
        # Unfortunately, __file__ is not available when cx_freeze is used or in IDLE.
        module_path = __file__
    except NameError:
        if len(sys.argv) > 0 and len(sys.argv[0]) > 0 and os.path.isabs(sys.argv[0]):
            module_path = sys.argv[0]
        else:
            module_path = os.path.abspath(inspect.getfile(GetScriptDirectory))
            if not os.path.exists(module_path):
                # If cx_freeze is used the value of the module_path variable at this point is in the following format.
                # {PathToExeFile}\{NameOfPythonSourceFile}. This makes it necessary to strip off the file name to get the correct
                # path.
                module_path = os.path.dirname(module_path)
    GetScriptDirectory.dir = os.path.dirname(module_path)
    return GetScriptDirectory.dir

sys.path.append(os.path.join(GetScriptDirectory(), "lib"))
print(GetScriptDirectory())
print(sys.path)

আপনি দেখতে পাচ্ছেন যে এটি কোনও সহজ কাজ নয়!


1

এটি আমার জন্য সবচেয়ে ভাল কাজ করে। ব্যবহার:

os.path.abspath('')

ম্যাক এ এটি এমন কিছু মুদ্রণ করা উচিত:

'/Users/<your username>/<path_to_where_you_at>'

বর্তমান ডাব্লুডির কাছে অ্যাবস পাথটি পেতে, এটি আরও ভাল কারণ এখন আপনি যদি চান তবে উপরে যেতে পারেন:

os.path.abspath('../')

এবং এখন:

 '/Users/<your username>/'

সুতরাং আপনি যদি utilsএখান থেকে আমদানি করতে চান তবে '/Users/<your username>/'
আপনার যা করতে হবে তা হ'ল:

import sys
sys.path.append(os.path.abspath('../'))

0

আমি আপনার উদাহরণে একটি শেবাং দেখতে পাচ্ছি। আপনি যদি ./bin/foo.pyপরিবর্তে আপনার বিন স্ক্রিপ্টগুলি চালাচ্ছেন তবে ভেরিয়েবল python ./bin/foo.pyপরিবর্তন করতে শেবাং ব্যবহারের বিকল্প রয়েছে $PYTHONPATH

আপনি সরাসরি শেবাংগুলিতে পরিবেশের পরিবর্তনগুলি পরিবর্তন করতে পারবেন না, সুতরাং আপনার জন্য একটি ছোট সহায়ক স্ক্রিপ্ট প্রয়োজন। python.shএটি আপনার binফোল্ডারে রাখুন :

#!/usr/bin/env bash
export PYTHONPATH=$PWD/lib
exec "/usr/bin/python" "$@"

এবং তারপরে আপনার ./bin/foo.pyহওয়ার শেবাং পরিবর্তন করুন change#!bin/python.sh


0

যখন আমরা টার্মিনাল থেকে পাথ দিয়ে পাইথন ফাইল চালানোর চেষ্টা করি।

import sys
#For file name
file_name=sys.argv[0]
#For first argument
dir= sys.argv[1]
print("File Name: {}, argument dir: {}".format(file_name, dir)

ফাইলটি সংরক্ষণ করুন (test.py)।

চলমান সিস্টেম।

টার্মিনালটি খুলুন এবং সেভ ফাইলটি সেভ করুন go তারপর লিখ

python test.py "/home/saiful/Desktop/bird.jpg"

প্রবেশ করুন

আউটপুট:

File Name: test, Argument dir: /home/saiful/Desktop/bird.jpg

0

আমি ব্যবহার করি:

from site import addsitedir

তারপরে, যে কোনও আপেক্ষিক ডিরেক্টরি ব্যবহার করতে পারেন! addsitedir('..\lib') ; দুটি বিন্দু প্রথমে একটি ডিরেক্টরি সরানো (উপরে) বোঝায়।

মনে রাখবেন যে এটি আপনার বর্তমান ওয়ার্কিং ডিরেক্টরি থেকে শুরু করে তার উপর নির্ভর করে। যদি সি: \ জো \ জেন \ বেকি হয়, তবে অ্যাডসটিডির ('.. \ lib') আপনার পথে সি আমদানি করে সি: \ জো \ জেন \ লিব

C:\
  |__Joe
      |_ Jen
      |     |_ Becky
      |_ lib

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