একটি প্যাকেজিং উপস্থাপক:
আপনি রিসোর্স ফাইলগুলি পড়ার বিষয়েও চিন্তাভাবনা করার আগে, প্রথম পদক্ষেপটি নিশ্চিত করা হয় যে ডেটা ফাইলগুলি প্রথমবারে আপনার বিতরণে প্যাকেজ হয়ে আসছে - সোর্স ট্রি থেকে তাদের সরাসরি পড়া সহজ, তবে গুরুত্বপূর্ণ অংশটি তৈরি করছে নিশ্চিত করুন যে এই সংস্থান ফাইলগুলি কোনও ইনস্টল করা প্যাকেজের মধ্যে কোড থেকে অ্যাক্সেসযোগ্য ।
প্যাকেজটির মধ্যে উপ-ডিরেক্টরিতে ডেটা ফাইল স্থাপন করে আপনার প্রকল্পটিকে এভাবে গঠন করুন :
.
├── package
│ ├── __init__.py
│ ├── templates
│ │ └── temp_file
│ ├── mymodule1.py
│ └── mymodule2.py
├── README.rst
├── MANIFEST.in
└── setup.py
include_package_data=True
আপনার setup()
কলটি পাস করা উচিত । ম্যানিফেস্ট ফাইলটি কেবলমাত্র তখনই প্রয়োজন হয় যদি আপনি সেটআপলগুলি / ডিস্টুয়েলগুলি ব্যবহার করতে এবং উত্স বিতরণ তৈরি করতে চান। templates/temp_file
এই উদাহরণস্বরূপ প্রকল্পের কাঠামোর জন্য প্যাকেজগুলি প্যাকেজ হয়ে গেছে তা নিশ্চিত করতে , ম্যানিফেস্ট ফাইলটিতে এর মতো একটি লাইন যুক্ত করুন:
recursive-include package *
.তিহাসিক ক্রাফট নোট: ফ্লিট, কবিতা ইত্যাদির মতো আধুনিক বিল্ড ব্যাকেন্ডের জন্য ম্যানিফেস্ট ফাইল ব্যবহারের প্রয়োজন নেই যা ডিফল্টরূপে প্যাকেজ ডেটা ফাইলগুলিকে অন্তর্ভুক্ত করবে। সুতরাং, আপনি যদি ব্যবহার করছেন pyproject.toml
এবং আপনার যদি কোনও setup.py
ফাইল না থাকে তবে আপনি সমস্ত জিনিস উপেক্ষা করতে পারেন MANIFEST.in
।
প্যাকেজিংয়ের বাইরে এখন পড়ার অংশে ...
প্রস্তাবনা:
স্ট্যান্ডার্ড গ্রন্থাগার pkgutil
API গুলি ব্যবহার করুন । এটি লাইব্রেরি কোডে এর মতো দেখতে যাচ্ছে:
import pkgutil
data = pkgutil.get_data(__name__, "templates/temp_file")
এটি জিপগুলিতে কাজ করে। এটি পাইথন 2 এবং পাইথন 3 এ কাজ করে It এটির জন্য তৃতীয় পক্ষের নির্ভরতা প্রয়োজন হয় না। আমি কোনও ডাউনসাইড সম্পর্কে সত্যই সচেতন নই (যদি আপনি থাকেন তবে উত্তরটি সম্পর্কে মন্তব্য করুন)।
খারাপ উপায়গুলি এড়াতে:
খারাপ উপায় # 1: উত্স ফাইল থেকে আপেক্ষিক পাথ ব্যবহার করা
এটি বর্তমানে গৃহীত উত্তর। সর্বোপরি, এটি দেখতে এমন কিছু দেখাচ্ছে:
from pathlib import Path
resource_path = Path(__file__).parent / "templates"
data = resource_path.joinpath("temp_file").read_bytes()
এতে কী ভুল? আপনার কাছে ফাইল এবং উপ-ডিরেক্টরি উপলভ্য অনুমানটি সঠিক নয়। একটি জিপ বা চাকাতে প্যাক করা কোডটি কার্যকর করলে এই পন্থাটি কার্যকর হয় না এবং আপনার প্যাকেজটি কোনও ফাইল সিস্টেমে আদৌ নেওয়া হয়েছে কিনা তা সম্পূর্ণ ব্যবহারকারীর নিয়ন্ত্রণের বাইরে থাকতে পারে।
খারাপ উপায় # 2: pkg_res উত্স API ব্যবহার করে
শীর্ষ ভোট প্রাপ্ত উত্তরে এটি বর্ণিত হয়েছে। এটি দেখতে এমন কিছু দেখাচ্ছে:
from pkg_resources import resource_string
data = resource_string(__name__, "templates/temp_file")
তাতে কি দোষ? এটি সেটআপলগুলিতে একটি রানটাইম নির্ভরতা যুক্ত করে , যা কেবলমাত্র একটি ইনস্টল সময় নির্ভরতা হওয়া উচিত । আপনার নিজের প্যাকেজ সংস্থানগুলিতে কেবল আগ্রহী থাকলেও কোডটি সমস্ত ইনস্টল করা প্যাকেজগুলির একটি ওয়ার্কিং সেট তৈরি করে, আমদানি করা এবং ব্যবহার করা সত্যিই ধীর হয়ে যেতে পারে । এটি ইনস্টলের সময় কোনও বড় বিষয় নয় (যেহেতু ইনস্টলেশনটি একবারে বন্ধ থাকে) তবে এটি রানটাইমের সময় কুরুচিপূর্ণ।pkg_resources
খারাপ উপায় # 3: Importlib.resources এপিআই ব্যবহার করে
এটি বর্তমানে শীর্ষ-ভোট প্রাপ্ত উত্তরের প্রস্তাবনা। এটি সাম্প্রতিক স্ট্যান্ডার্ড গ্রন্থাগার সংযোজন ( পাইথন ৩.7 এ নতুন )। দেখে মনে হচ্ছে:
from importlib.resources import read_binary
data = read_binary("package.templates", "temp_file")
তাতে কি দোষ? ঠিক আছে, দুর্ভাগ্যক্রমে, এটি এখনও কাজ করে না ... এটি এখনও একটি অসম্পূর্ণ এপিআই, ব্যবহারের importlib.resources
জন্য আপনাকে একটি খালি ফাইল যুক্ত করতে হবে templates/__init__.py
যাতে ডেটা ফাইলগুলি একটি উপ-ডিরেক্টরিতে না হয়ে উপ-প্যাকেজের মধ্যে থাকবে। এটি সাব- package/templates
ডাইরেক্টরিটিকে নিজস্বভাবে আমদানিযোগ্য package.templates
উপ-প্যাকেজ হিসাবে প্রকাশ করবে । যদি এটি কোনও বড় বিষয় না হয় এবং এটি আপনাকে বিরক্ত করে না, তবে আপনি এগিয়ে গিয়ে __init__.py
সেখানে ফাইল যুক্ত করতে এবং সংস্থানগুলি অ্যাক্সেস করতে আমদানি সিস্টেমটি ব্যবহার করতে পারেন। যাইহোক, আপনি যখন এটি উপস্থিত তখন আপনি এটির my_resources.py
পরিবর্তে একটি ফাইল তৈরি করতে পারেন এবং মডিউলটিতে কিছু বাইট বা স্ট্রিং ভেরিয়েবল সংজ্ঞায়িত করুন, তারপরে পাইথন কোডে সেগুলি আমদানি করুন। এটি এখানে যে কোনও উপায়ে ভারী উত্তোলন আমদানি ব্যবস্থা।
সম্মানজনক উল্লেখ: আরও নতুন আমদানিলিবি_স্রোত এপিআই ব্যবহার করে
এটি এখনও অন্য কোনও importlib_resources
উত্তরে উল্লেখ করা হয়নি, তবে পাইথন ৩ importlib.resources
. ++ কোডের সাধারণ ব্যাকপোর্টের চেয়ে বেশি । এটিতে ট্র্যাভারেজেবল এপিআই রয়েছে যা আপনি এটির মতো ব্যবহার করতে পারেন:
import importlib_resources
my_resources = importlib_resources.files("package")
data = (my_resources / "templates" / "temp_file").read_bytes()
এটি পাইথন 2 এবং 3 তে কাজ করে, এটি জিপগুলিতে কাজ করে, এবং এটি __init__.py
উত্স-সাব-ডিরেক্টরিতে উত্সাহিত ফাইল যুক্ত করার প্রয়োজন হয় না । শুধুমাত্র downside হয় বনাম pkgutil
যে আমি দেখতে পারবেন, সুতরাং এখনও একটি তৃতীয় পক্ষের নির্ভরতা হয়, যে এই নতুন API গুলি এখনো stdlib আগত নি। থেকে নতুন এপিআইগুলি পাইথন ৩.৯-এ importlib_resources
স্টাডলিব পৌঁছানো উচিত importlib.resources
।
প্রকল্প উদাহরণ:
আমি গিথুবের উপর একটি উদাহরণ প্রকল্প তৈরি করেছি এবং পিপিআইতে আপলোড করেছি , যা উপরে আলোচিত পাঁচটি পদ্ধতিরই প্রদর্শন করে। এটি দিয়ে চেষ্টা করে দেখুন:
$ pip install resources-example
$ resources-example
আরও তথ্যের জন্য https://github.com/wimglenn/resources-example দেখুন ।