কোড সংগ্রহস্থলের সাথে কাজ করার সময় কীভাবে সংস্থানসমূহের আপেক্ষিক পাথগুলি উল্লেখ করা যায়


187

আমরা একটি কোড সংগ্রহস্থল নিয়ে কাজ করছি যা উইন্ডোজ এবং লিনাক্স উভয় ক্ষেত্রেই স্থাপন করা হয় - কখনও কখনও বিভিন্ন ডিরেক্টরিতে। প্রকল্পের অভ্যন্তরে যে কোনও একটি মডিউল কীভাবে প্রকল্পের একটি পাইথন বিহীন সংস্থানগুলির (সিএসভি ফাইল ইত্যাদি) বোঝায়?

আমরা যদি এমন কিছু করি:

thefile=open('test.csv')

বা:

thefile=open('../somedirectory/test.csv')

স্ক্রিপ্টটি কোনও নির্দিষ্ট ডিরেক্টরি, বা ডিরেক্টরিগুলির একটি উপসেট থেকে চালিত হলেই এটি কাজ করবে।

আমি যা করতে চাই তা হ'ল:

path=getBasePathOfProject()+'/somedirectory/test.csv'
thefile=open(path)

এটা কি সম্ভব?

উত্তর:


255

বর্তমান ফাইলগুলির সাথে সম্পর্কিত ফাইলের নাম ব্যবহার করার চেষ্টা করুন। './My_file' এর উদাহরণ:

fn = os.path.join(os.path.dirname(__file__), 'my_file')

পাইথন ৩.৪++ এ আপনি পাথলিবও ব্যবহার করতে পারেন :

fn = pathlib.Path(__file__).parent / 'my_file'

3
আমি মনে করি এই সমাধানটি কেবল তখনই কাজ করবে যদি সংস্থানটি পাইথন ফাইলের একই ডিরেক্টরিতে হয় বা এর একটি ডিরেক্টরিতে থাকে। আপনার নীচের গাছের কাঠামো থাকলে আপনি কীভাবে এটি সমাধান করবেন: / প্রকল্প_রূট_ডির / পাইথন_ফায়ালস_ডির / আরও কিছু সাবডিয়ার এখানে আছে py_file.py / রিসোর্সস / কিছু সাবডিয়ার এখানে
রিসোর্স_ফাইলসিএসভি

1
দুঃখিত, ফাইল ট্রিটি সেই শেষ বার্তায় ফোটে ... দ্বিতীয়বার চেষ্টা করুন: আপনার ফাইলটি / প্রকল্প / রুট_ডির / প্যাথন_ফিলার_ডির / সুম_সুবিডার / স্পি.ফাইল.পি এ রয়েছে এবং আপনার / প্রোজেক্ট_রूट_ডির / রিসোর্স / সাইম_সুবদিয়ারস
ওলমুন্ডো

28
আপনি যোগ দিন (foo, '..') ব্যবহার করে প্যারেন্ট ডিরেক্টরিতে যেতে সক্ষম হবেন। সুতরাং / রুট / পাইথন_ফায়ালস / মডিউল / মাইফাইল থেকে, os.path.join (os.path.dirname ( __file__), '..', '..', 'রিসোর্স') ব্যবহার করুন
c089

7
os.pardir'..'দু'টি POSIX এবং Windows উভয়ের সমতুল্য হলেও এর চেয়ে কিছুটা ভাল better
ডেভিডচেম্বার

4
@cedbeu: এটি আমি যে সমস্ত সিস্টেমের মধ্য দিয়ে এসেছি তার সমান এবং আমি মনে করি আজকের প্রতিটি সিস্টেম অজগর চলছে (দয়া করে এখানে আমি ভুল হলে আমাকে সংশোধন করুন)। তবে, আপনি যদি আশা করেন যে অজগরটি ভবিষ্যতে অন্য একটি পৃথক পাথ বিভাজক ব্যবহার করে কোনও সিস্টেমে পোর্ট করা হবে এবং আপনার কোডটি এর জন্য প্রস্তুত থাকতে চান, তবে os.pardir আরও বহনযোগ্য হবে। আমি এমন কেসটি তৈরি করবো যে প্রতিটি প্রোগ্রামার, এমনকি যে কোনও পাইথনটি কখনও পড়েনি সে ".." এর অর্থ জানে না, যখন "os.pardir" ইন্ডিয়ারেশনের একটি স্তর, তাই ডকুমেন্টেশনে ব্যক্তিগতভাবে দেখা উচিত আমিই ' "স্টাইল" .. "।
c089

40

আপনি যদি সেটআপ সরঞ্জাম ব্যবহার করেন বা বিতরণ করেন (একটি সেটআপ.পি ইনস্টল) তবে এই প্যাকেজযুক্ত সংস্থানগুলিতে অ্যাক্সেসের "ডান" উপায়টি প্যাকেজ_সোর্সগুলি ব্যবহার করে বলে মনে হচ্ছে।

আপনার ক্ষেত্রে উদাহরণ হতে হবে

import pkg_resources
my_data = pkg_resources.resource_string(__name__, "foo.dat")

অবশ্যই কোনটি রিসোর্সটি পড়বে এবং বাইনারি ডেটা পড়বে তা আমার_ডাটার মান হবে

আপনার যদি কেবলমাত্র ফাইলের প্রয়োজন হয় তবে আপনি এটিও ব্যবহার করতে পারেন

resource_filename(package_or_requirement, resource_name)

উদাহরণ:

resource_filename("MyPackage","foo.dat")

সুবিধাটি হ'ল এটি ডিমের মতো সংরক্ষণাগার বিতরণ হলেও কাজ করার গ্যারান্টিযুক্ত।

দেখুন http://packages.python.org/distribute/pkg_resources.html#resourcemanager-api


3
আমি জানি এটি একটি পুরানো উত্তর, আমার পছন্দের উপায়টি (/ হতে পারে?) পিকেজি_সোর্সগুলি ব্যবহার করার জন্য, তবে জিপড ডিম অদৃশ্য হওয়ার সাথে, কেবল __file__ভাল পুরানো দিনের মতো ব্যবহার করার কোনও ক্ষতি আছে কি?
পাইকলার

1
এটি একটি দৃ approach় পদ্ধতির। এমনকি ডিমের কনভেনশন চলে গেলেও সেটআপটুলগুলি হয় না এবং অনেকে এখনও গিট রেপোর বিপরীতে ডিপগুলি ইনস্টল করে থাকেন যেখানে রানটাইম সময়ে ডিম তৈরি করা হয়

18

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

পরম পাথ ব্যবহার করা সর্বোত্তম সমাধান হওয়া উচিত:

import os
package_dir = os.path.dirname(os.path.abspath(__file__))
thefile = os.path.join(package_dir,'test.cvs')

15

আমি প্রায়শই এর অনুরূপ কিছু ব্যবহার করি:

import os
DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), 'datadir'))

# if you have more paths to set, you might want to shorten this as
here = lambda x: os.path.abspath(os.path.join(os.path.dirname(__file__), x))
DATA_DIR = here('datadir') 

pathjoin = os.path.join
# ...
# later in script
for fn in os.listdir(DATA_DIR):
    f = open(pathjoin(DATA_DIR, fn))
    # ...

পরিবর্তনশীল

__file__

আপনি সেই কোডটিতে যে স্ক্রিপ্টটি লিখেছেন তার ফাইলের নাম ধারণ করে, যাতে আপনি স্ক্রিপ্টের সাথে তুলনামূলক পাথ তৈরি করতে পারেন তবে এখনও নিখুঁত পাথ দিয়ে লেখা written এটি বেশ কয়েকটি কারণে বেশ ভাল কাজ করে:

  • পথ নিখুঁত, তবে এখনও আপেক্ষিক
  • প্রকল্পটি এখনও কোনও আপেক্ষিক পাত্রে স্থাপন করা যেতে পারে

তবে আপনাকে প্ল্যাটফর্মের সামঞ্জস্যের জন্য নজর রাখা দরকার - উইন্ডোজের ..pathsep ইউনিক্সের চেয়ে আলাদা।


5
import os
cwd = os.getcwd()
path = os.path.join(cwd, "my_file")
f = open(path)

আপনি নিজের cwdব্যবহারকে স্বাভাবিক করার চেষ্টা করুন os.path.abspath(os.getcwd())। আরও তথ্য এখানে


3
খুব কম ব্যবহারের ক্ষেত্রে যেখানে cwdএকটি মডিউলটির পথ, যদিও
সিডবেউ

এটি কোনও প্যাকেজের অভ্যন্তরে কাজ করে না, কেবল একই স্ক্রিপ্ট দ্বারা নির্ধারিত দির (বা কার্যকরী ডির) থেকে।
আলেকজান্দ্রা

ব্যবহারকারী যদি বিভিন্ন ডিরেক্টরি থেকে পরম পথ ব্যবহার করে প্রোগ্রাম চালায় তবে এটি কাজ করবে না। যেমন পাইথন 3 /usr/someone/test.py
sgrpwr

2

আপনি বিল্ড ইন __file__ভেরিয়েবল ব্যবহার করতে পারেন । এটিতে বর্তমান ফাইলের পথ রয়েছে। আমি আপনার প্রকল্পের মূলের একটি মডিউলে getBaseOfProject বাস্তবায়ন করব। সেখানে আমি পথের অংশটি পেয়ে যাব __file__এবং তা ফেরত দেব। এই পদ্ধতিটি তখন আপনার প্রকল্পের সর্বত্র ব্যবহার করা যেতে পারে।


0

আমি এখানে কিছুটা স্টম্পড হয়ে গেলাম। কিছু রিসোর্স ফাইলকে হুইল ফাইলে প্যাকেজ করতে এবং সেগুলিতে অ্যাক্সেস করতে চেয়েছিল। ম্যানিফেস্ট ফাইল ব্যবহার করে কি প্যাকেজিং হয়েছে, তবে পাইপ ইনস্টলটি এটি কোনও উপ ডিরেক্টরি না হলে এটি ইনস্টল করে না। এই মনোরম শটগুলি আশা করা সাহায্য করবে

├── cnn_client
   ├── image_preprocessor.py
   ├── __init__.py
   ├── resources
      ├── mscoco_complete_label_map.pbtxt
      ├── retinanet_complete_label_map.pbtxt
      └── retinanet_label_map.py
   ├── tf_client.py

MANIFEST.in

recursive-include cnn_client/resources *

স্ট্যান্ডার্ড সেটআপ.পি ব্যবহার করে একটি ওয়েল তৈরি করেছে। পাইপ ইনস্টল হুইল ফাইল। সংস্থার পরে রিসোর্স ইনস্টল করা আছে কিনা তা পরীক্ষা করে দেখুন। তারা হয়

ls /usr/local/lib/python2.7/dist-packages/cnn_client/resources

mscoco_complete_label_map.pbtxt
retinanet_complete_label_map.pbtxt 
 retinanet_label_map.py  

Tfclient.py এ এই ফাইলগুলি অ্যাক্সেস করতে। থেকে

templates_dir = os.path.join(os.path.dirname(__file__), 'resources')
 file_path = os.path.join(templates_dir, \
            'mscoco_complete_label_map.pbtxt')
        s = open(file_path, 'r').read()

এবং এটি কাজ করে।


-5

আমি এর উত্তর খুঁজে পেতে দীর্ঘ সময় ব্যয় করেছি, তবে শেষ পর্যন্ত এটি পেয়েছি (এবং এটি আসলেই সহজ):

import sys
import os
sys.path.append(os.getcwd() + '/your/subfolder/of/choice')

# now import whatever other modules you want, both the standard ones,
# as the ones supplied in your subfolders

এটি আপনার সাবফোল্ডারটির আপেক্ষিক পথটি অজগরটির জন্য ডিরেক্টরিগুলিতে সংযোজন করবে এটি দেখতে খুব তাড়াতাড়ি এবং নোংরা, তবে এটি একটি কবজির মতো কাজ করে :)


6
এটি কেবল তখনই কাজ করবে যদি আপনি প্রশ্নে থাকা .py ফাইল হিসাবে একই ডিরেক্টরি থেকে পাইথন প্রোগ্রামটি চালাচ্ছেন। এবং open('your/subfolder/of/choice')সেক্ষেত্রে আপনি যেভাবেই করতে পারেন ।
পল ফিশার

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