পাইথন স্ক্রিপ্টের মতো একই ডিরেক্টরিতে কোনও ফাইলকে কীভাবে নির্ভরযোগ্যভাবে খুলতে হয়


157

আমি বর্তমানে চলমান পাইথন স্ক্রিপ্টের মতো একই কমান্ড ব্যবহার করে ফাইলগুলি খুলতাম

open("Some file.txt", "r")

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

সেই থেকে আমি ফর্মটির একটি কমান্ড ব্যবহার করেছি

open(os.path.join(sys.path[0], "Some file.txt"), "r")

যখনই আমি কোনও ফাইল খুলতে চাইতাম। এটি আমার নির্দিষ্ট ব্যবহারের জন্য কাজ করে তবে আমি নিশ্চিত নই যে sys.path[0]অন্য কোনও ব্যবহারের ক্ষেত্রেও এটি ব্যর্থ হতে পারে।

সুতরাং আমার প্রশ্নটি: বর্তমানে চলমান পাইথন স্ক্রিপ্টের একই ডিরেক্টরিতে থাকা কোনও ফাইল খোলার সর্বোত্তম এবং নির্ভরযোগ্য উপায় কোনটি?

আমি এখন অবধি বুঝতে সক্ষম হয়েছি এখানে এখানে:

  • os.getcwd()এবং os.path.abspath('')"বর্তমান ওয়ার্কিং ডিরেক্টরি" ফিরিয়ে দিন, স্ক্রিপ্ট ডিরেক্টরি নয়।

  • os.path.dirname(sys.argv[0])এবং os.path.dirname(__file__)স্ক্রিপ্টটি কল করার জন্য ব্যবহৃত পথটি ফিরে আসুন, যা আপেক্ষিক বা এমনকি ফাঁকা হতে পারে (যদি স্ক্রিপ্টটি সিডব্লিউডে থাকে)। এছাড়াও, __file__যখন স্ক্রিপ্টটি IDLE বা পাইথনওয়িনে চালিত হয় তখন উপস্থিত থাকে না।

  • sys.path[0]এবং os.path.abspath(os.path.dirname(sys.argv[0]))স্ক্রিপ্ট ডিরেক্টরি ফিরে বলে মনে হচ্ছে। আমি নিশ্চিত না যে এই দুটিয়ের মধ্যে কোনও পার্থক্য আছে কিনা।

সম্পাদনা:

আমি কেবল বুঝতে পেরেছি যে আমি যা করতে চাই তার আরও ভালভাবে বর্ণনা করা হবে "সমেত মডিউলযুক্ত একই ডিরেক্টরিতে একটি ফাইল খুলুন"। অন্য কথায়, আমি যদি কোনও মডিউল আমদানি করি তবে আমি লিখেছিলাম যে এটি অন্য ডিরেক্টরিতে রয়েছে এবং সেই মডিউলটি একটি ফাইল খুলবে, আমি মডিউলটির ডিরেক্টরিতে ফাইলটি সন্ধান করতে চাই। আমি মনে করি না যে আমি কিছু পেয়েছি তা করতে সক্ষম ...

উত্তর:


199

আমি সবসময় ব্যবহার:

__location__ = os.path.realpath(
    os.path.join(os.getcwd(), os.path.dirname(__file__)))

join()কল সাম্প্রতিক কাজ করা prepends কিন্তু ডকুমেন্টেশন বলছেন যে যদি কিছু পথ পরম অন্যান্য সমস্ত পাথ এটা বাম বাদ করছে। অতএব, getcwd()বাদ দেওয়া হয় যখন dirname(__file__)পরম পাথ ফিরে আসে।

এছাড়াও, realpathকলটি পাওয়া গেলে প্রতীকী লিঙ্কগুলি সমাধান করে। লিনাক্স সিস্টেমে সেটআপলগুলি স্থাপন করার সময় সমস্যাগুলি এড়ানো যায় (স্ক্রিপ্টগুলিতে প্রতিলিপি তৈরি করা হয় /usr/bin/- কমপক্ষে ডেবিয়ানে)।

আপনি একই ফোল্ডারে ফাইলগুলি খোলার জন্য নিম্নলিখিত ব্যবহার করতে পারেন:

f = open(os.path.join(__location__, 'bundled-resource.jpg'));
# ...

আমি এটি উইন্ডোজ এবং লিনাক্স উভয়টিতে বেশ কয়েকটি জ্যাঙ্গো অ্যাপ্লিকেশন সহ সংস্থানগুলি বান্ডিল করতে ব্যবহার করি এবং এটি একটি কবজির মতো কাজ করে!


4
যদি __file__ব্যবহার না করা যায় তবে তার sys.argv[0]পরিবর্তে ব্যবহার করুন dirname(__file__)। বাকিদের প্রত্যাশা অনুযায়ী কাজ করা উচিত। আমি __file__লাইব্রেরি কোডে ব্যবহার করা পছন্দ করি , sys.argv[0]সম্ভবত আপনার কোডটির দিকে নির্দেশ নাও করতে পারে, বিশেষত যদি কোনও তৃতীয় পক্ষের স্ক্রিপ্টের মাধ্যমে আমদানি করা হয়।
আন্দ্রে কারন 19

1
এটির সাথে সমস্যাটি হ'ল যদি আপনি চালিত ফাইলটি সরাসরি বাধা থেকে আসে বা এটি আমদানি করা হয়। ফাইল এবং sys.argv মধ্যে পার্থক্যের জন্য আমার উত্তর দেখুন [0]
Zimm3r

সুতরাং জিম্ম 3 আর এর উত্তরে বর্ণিত বৈচিত্রটি realpath( join( getcwd(), dirname(__file__) ))এখানে বর্ণিত হিসাবে ব্যবহার করে সম্বোধন করা ঠিক কি সঠিক ?
পিয়ানোজেমস 16

44

পাইথন ডকুমেন্টেশন থেকে উদ্ধৃতি:

প্রোগ্রাম শুরু হওয়ার পরে, সূচকের প্রথম আইটেম, পাথ [0], হ'ল ডিরেক্টরিটি স্ক্রিপ্টযুক্ত পাইথন ইন্টারপ্রেটারকে অনুরোধ করার জন্য ব্যবহৃত হত। যদি স্ক্রিপ্ট ডিরেক্টরিটি উপলভ্য না হয় (উদাহরণস্বরূপ যদি ইন্টারপ্রিটার ইন্টারেক্টিভভাবে ডাকা হয় বা স্ক্রিপ্টটি স্ট্যান্ডার্ড ইনপুট থেকে পড়ে থাকে), পথ [0] হ'ল ফাঁকা স্ট্রিং, যা পাইথনকে বর্তমান ডিরেক্টরিতে প্রথমে মডিউলগুলি সন্ধান করতে নির্দেশ দেয়। লক্ষ করুন যে পাইথনপথের ফলে প্রবেশের প্রবেশের আগে স্ক্রিপ্ট ডিরেক্টরিটি সন্নিবেশ করা হয়েছে।

sys.path [0] আপনি যা খুঁজছেন তা।


10
এবং ফাইল সম্পূর্ণ পাথ জন্য: os.path.join(sys.path[0], 'some file.txt')। এটিতে সমস্ত সিস্টেমে সঠিকভাবে স্পেস এবং স্ল্যাশ পরিচালনা করা উচিত।
জ্যাকটোজ

প্রথম প্রশ্নের এই উত্তর, ইডিআইটির পরে এক নয়।
mcoolive

22

ঠিক আছে এখানে আমি কি করি

pysthon.exe বা pythonw.exe দিয়ে সঞ্চালনের সময় আপনি টার্মিনালে যা টাইপ করেন বা ফাইল পথ হিসাবে ব্যবহার করেন তা সর্বদা sys.argv হয় is

উদাহরণস্বরূপ আপনি ফাইলটি টেক্সট.পি চালিয়ে যেতে পারেন বেশ কয়েকটি উপায়ে, তারা প্রত্যেকে আপনাকে আলাদা উত্তর দেয় তারা সর্বদা আপনাকে পাইথন টাইপ করার পথটি দেয়।

    C:\Documents and Settings\Admin>python test.py
    sys.argv[0]: test.py
    C:\Documents and Settings\Admin>python "C:\Documents and Settings\Admin\test.py"
    sys.argv[0]: C:\Documents and Settings\Admin\test.py

ঠিক আছে তাই জেনে নিন আপনি এখন ফাইলের নাম পেতে পারেন, দুর্দান্ত চুক্তি করতে পারেন, এখন অ্যাপ্লিকেশন ডিরেক্টরি পেতে আপনি জানতে পারেন os.path, বিশেষত অ্যাবস্পাথ এবং dirname

    import sys, os
    print os.path.dirname(os.path.abspath(sys.argv[0]))

এটি এটিকে আউটপুট দেবে:

   C:\Documents and Settings\Admin\

আপনি পাইথন টেস্ট.পি বা পাইথন "সি: \ ডকুমেন্টস এবং সেটিংস \ অ্যাডমিন \ টেস্ট.পি" টাইপ করলে এটি সর্বদা এটির ফলাফল দেয়

__File__ ব্যবহার করতে সমস্যা এই দুটি ফাইল পরীক্ষা করুন

import sys
import os

def paths():
        print "__file__: %s" % __file__
        print "sys.argv: %s" % sys.argv[0]

        a_f = os.path.abspath(__file__)
        a_s = os.path.abspath(sys.argv[0])

        print "abs __file__: %s" % a_f
        print "abs sys.argv: %s" % a_s

if __name__ == "__main__":
    paths()

import_test.py

import test
import sys

test.paths()

print "--------"
print __file__
print sys.argv[0]

"পাইথন টেস্ট.পি" এর আউটপুট

C:\Documents and Settings\Admin>python test.py
__file__: test.py
sys.argv: test.py
abs __file__: C:\Documents and Settings\Admin\test.py
abs sys.argv: C:\Documents and Settings\Admin\test.py

"পাইথন টেস্ট_মম্পোর্ট.পি" এর আউটপুট

C:\Documents and Settings\Admin>python test_import.py
__file__: C:\Documents and Settings\Admin\test.pyc
sys.argv: test_import.py
abs __file__: C:\Documents and Settings\Admin\test.pyc
abs sys.argv: C:\Documents and Settings\Admin\test_import.py
--------
test_import.py
test_import.py

আপনি যেমন ফাইলটি দেখতে পাচ্ছেন এটি আপনাকে সর্বদা পাইথন ফাইল দেয় যা এটি চালিত হচ্ছে, যেখানে sys.argv [0] আপনাকে ফাইলটি দেয় যা আপনি সবসময় দোভাষী থেকে দৌড়েছিলেন। আপনার প্রয়োজনের উপর নির্ভর করে আপনার চয়ন করতে হবে আপনার মধ্যে কোনটি সবচেয়ে ভাল ফিট করে।


3
এটি একটি বিস্তৃত প্রমাণ যা বাস্তবায়ন ডকুমেন্টেশনকে প্রতিবিম্বিত করে। __file__হয় অনুমিত "সর্বদা আপনি বর্তমান ফাইল পাথ দিতে", এবং sys.argv[0]হয় অনুমিত "সবসময় স্ক্রিপ্ট যে প্রক্রিয়া শুরু পথ দিতে" করা হয়েছে। যাই হোক __file__না কেন, স্ক্রিপ্টটিতে যা সর্বদা আমন্ত্রণ জানায় তা আপনাকে সুনির্দিষ্ট ফলাফল দেয়।
আন্দ্রে কারন

আপনার যদি __file__স্ক্রিপ্টের শীর্ষ স্তরের রেফারেন্স থাকে তবে এটি প্রত্যাশার মতো কাজ করবে।
ম্যাথু শিনকেল

-1

নির্দিষ্ট পাঠ্য ফাইলটি পড়ার ক্ষেত্রে আমার একই রকম সমস্যা হওয়ায় আমি সাফল্যের সাথে ডকোলিশের সরবরাহকৃত কোডটি ব্যবহার করতে সক্ষম হয়েছি। ফাইলটি পাইথন ফাইলের মতো একই সিডব্লিউডে নেই।


1
উত্তর হিসাবে "ধন্যবাদ" যোগ করবেন না। আপনার যথেষ্ট খ্যাতি অর্জনের পরে , আপনি যে প্রশ্নগুলি এবং সহায়ক বলে মনে করেছিলেন সেগুলি জবাব দিতে সক্ষম হবেন । - পর্যালোচনা থেকে
রবার্তো ক্যাবনি

-3

আমি এটি এইভাবে করব:

from os.path import abspath, exists

f_path = abspath("fooabar.txt")

if exists(f_path):
    with open(f_path) as f:
        print f.read()

উপরের কোডটি অ্যাবস্পাথ ব্যবহার করে ফাইলের জন্য একটি পরম পথ তৈরি করে এবং normpath(join(os.getcwd(), path))[এটি পাইডোকস থেকে] ব্যবহারের সমতুল্য । তারপরে এটি ফাইলটি আসলে উপস্থিত রয়েছে কিনা তা পরীক্ষা করে এবং এটি খোলার জন্য একটি প্রসঙ্গ পরিচালক ব্যবহার করে যাতে আপনাকে ফাইল হ্যান্ডেলটিতে কল করতে হবে না। আইএমএইচও, এইভাবে এটি আপনাকে দীর্ঘমেয়াদে অনেক ব্যথা বাঁচায়।


এটি পোস্টারের প্রশ্নের উত্তর দেয় না। dln385 সুনির্দিষ্টভাবে বলেছিল যে os.path.abspathস্ক্রিপ্টটি বর্তমান ডিরেক্টরিতে না থাকলে স্ক্রিপ্টের মতো একই ফোল্ডারে ফাইলগুলির পাথগুলি সমাধান করে না।
আন্দ্রে কারন

আহ! আমি ধরে নিয়েছিলাম যে ব্যবহারকারী এই স্ক্রিপ্টটি যে ফাইলটি পড়তে চেয়েছিলেন ঠিক সেভাবেই এই স্ক্রিপ্টটি চালাচ্ছিলেন, তাদের পাইথনপথের কোনও মডিউল ডিয়ারে নয় । এটি আমাকে অনুমান করা শিখিয়ে দেবে ...
ডিসক্লিশ করুন

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