পাইথন প্যাকেজের ভিতরে থেকে কী (স্ট্যাটিক) ফাইল পড়বেন?


117

আপনি কি আমাকে বলতে পারবেন যে আমার পাইথন প্যাকেজের ভিতরে থাকা কোনও ফাইল আমি কীভাবে পড়তে পারি?

আমার অবস্থা

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

কল্পনা করুন যে আমি একটি ফাইল পড়তে চাই:

package\templates\temp_file

এক ধরণের পথের কারসাজি? প্যাকেজ বেস পাথ ট্র্যাকিং?


উত্তর:


-13

[২০১-0-০6-১ added যোগ করা হয়েছে: দৃশ্যত এটি সমস্ত পরিস্থিতিতে কাজ করে না। অন্যান্য উত্তর দেখুন]


import os, mypackage
template = os.path.join(mypackage.__path__[0], 'templates', 'temp_file')

188

টিএলডিআর; নীচে নং 2 নং পদ্ধতিতে বর্ণিত হিসাবে স্ট্যান্ডার্ড-লাইব্রেরির importlib.resourcesমডিউলটি ব্যবহার করুন ।

From তিহ্যগত pkg_resourcesথেকেsetuptools আর সুপারিশ করা হয় না কারণ নতুন পদ্ধতি:

  • এটি উল্লেখযোগ্যভাবে আরও পারফরম্যান্ট ;
  • প্যাকেজগুলির ব্যবহার (পাথ-স্টিংসের পরিবর্তে) সংকলন-সময় ত্রুটিগুলি বাড়ানোর কারণে এটি নিরাপদ;
  • এটি আরও স্বজ্ঞাত যেহেতু আপনাকে "যোগ" দিতে হবে না;
  • এটি যখন আপনার অতিরিক্ত নির্ভরতা ( setuptools) প্রয়োজন হয় না, তখন এটি তত দ্রুত হয় তবে পাইথনের স্ট্যান্ডার্ড-লাইব্রেরিতে একা নির্ভর করুন।

বিদ্যমান কোডের পোর্টিং করার সময় নতুন পদ্ধতির সাথে পার্থক্যগুলি বর্ণনা করার জন্য আমি প্রথমে তালিকাভুক্ত keptতিহ্যবাহী রেখেছি (পোর্টিংটি এখানেও ব্যাখ্যা করা হয়েছে )।



আসুন ধরে নেওয়া যাক আপনার টেম্পলেটগুলি আপনার মডিউলটির প্যাকেজের অভ্যন্তরের কোনও ফোল্ডারে অবস্থিত:

  <your-package>
    +--<module-asking-the-file>
    +--templates/
          +--temp_file                         <-- We want this file.

দ্রষ্টব্য 1: নিশ্চিতভাবেই, আমাদের __file__গুণাবলীর সাথে গলগল করা উচিত নয় (উদাহরণস্বরূপ জিপ থেকে পরিবেশন করার সময় কোডটি ভেঙে যাবে)।

উল্লেখ্য 2: আপনি এই প্যাকেজ নির্মাণ করা হয় তাহলে, যেমন আপনার ডেটা ফাইল declatre মনে রাখবেন package_dataবাdata_files আপনার setup.py

1) (ধীর) pkg_resourcesথেকে ব্যবহার করাsetuptools

আপনি সেটআপলগুলি বিতরণ pkg_resourcesথেকে প্যাকেজটি ব্যবহার করতে পারেন , তবে এটি ব্যয়, পারফরম্যান্স- ভিত্তিতে আসে :

import pkg_resources

# Could be any dot-separated package/module name or a "Requirement"
resource_package = __name__
resource_path = '/'.join(('templates', 'temp_file'))  # Do not use os.path.join()
template = pkg_resources.resource_string(resource_package, resource_path)
# or for a file-like stream:
template = pkg_resources.resource_stream(resource_package, resource_path)

পরামর্শ:

  • এই ডেটা পড়তে হবে এমনকি যদি আপনার বন্টন জিপ করা, তাই আপনি সেট করতে পারেন zip_safe=Trueআপনার setup.pyএবং / অথবা দীর্ঘ প্রতীক্ষিত ব্যবহার zipappপ্যাকার থেকে পাইথন-3.5 স্বয়ংসম্পূর্ণ ডিস্ট্রিবিউশন তৈরি করুন।

  • setuptoolsআপনার রান-টাইম প্রয়োজনীয়তাগুলিতে যুক্ত করতে ভুলবেন না (উদাহরণস্বরূপ ইনস্টল_আরকিয়ারস)।

... এবং লক্ষ্য করুন যে সেটআপলগুলি / pkg_resourcesডক্স অনুসারে আপনার ব্যবহার করা উচিত নয় os.path.join:

বেসিক রিসোর্স অ্যাক্সেস

মনে রাখবেন যে /উত্সের নাম অবশ্যই পৃথক পৃথক পাথের হতে হবে এবং পরম হতে পারে না (যেমন কোনও অগ্রণী নয় /) বা " .." এর মতো আপেক্ষিক নাম থাকতে পারে না । না না ব্যবহার os.pathরুটিন রিসোর্স পাথ নিপূণভাবে, হিসাবে তারা না ফাইলসিস্টেম পাথ।

2) পাইথন> = 3.7, বা ব্যাকপোর্টেড importlib_resourcesলাইব্রেরি ব্যবহার করে

স্ট্যান্ডার্ড লাইব্রেরির importlib.resourcesমডিউলটি ব্যবহার করুন যা setuptoolsউপরের তুলনায় আরও দক্ষ :

try:
    import importlib.resources as pkg_resources
except ImportError:
    # Try backported to PY<37 `importlib_resources`.
    import importlib_resources as pkg_resources

from . import templates  # relative-import the *package* containing the templates

template = pkg_resources.read_text(templates, 'temp_file')
# or for a file-like stream:
template = pkg_resources.open_text(templates, 'temp_file')

মনোযোগ:

কার্য সম্পর্কিত read_text(package, resource):

  • এটি packageস্ট্রিং বা মডিউল হতে পারে।
  • resourceআর একটি পথ, কিন্তু খোলা রিসোর্স, কোনো বিদ্যমান প্যাকেজ মধ্যে ফাইলের নাম নয়; এটিতে পথ বিভাজক নাও থাকতে পারে এবং এর উপ-সংস্থান নাও থাকতে পারে (যেমন এটি ডিরেক্টরি হতে পারে না)।

প্রশ্নে জিজ্ঞাসিত উদাহরণের জন্য আমাদের এখনই:

  • করতে <your_package>/templates/ একটি সঠিক প্যাকেজ মধ্যে, একটি খালি তৈরি করে __init__.pyতাতে ফাইল,
  • সুতরাং এখন আমরা একটি সাধারণ (সম্ভবত আপেক্ষিক) importস্টেটমেন্ট ব্যবহার করতে পারি ( প্যাকেজ / মডিউলের আরও কোনও পার্সিং নেই),
  • এবং কেবল resource_name = "temp_file"(কোনও পথের) জন্য জিজ্ঞাসা করুন ।

পরামর্শ:

  • বর্তমান মডিউলটির মধ্যে একটি ফাইল অ্যাক্সেস করতে প্যাকেজ আর্গুমেন্টটি সেট করুন __package__, যেমন pkg_resources.read_text(__package__, 'temp_file')(@ বেন-মেরেসকে ধন্যবাদ)।
  • কিছু আকর্ষণীয় হয়ে যখন একটি প্রকৃত ফাইলের নাম দিয়ে বলা হয় path(), যেহেতু এখন প্রসঙ্গ পরিচালকের সাময়িকভাবে তৈরি ফাইলগুলি (পড়া জন্য ব্যবহার করা হয় এই )।
  • সঙ্গে, শর্তসাপেক্ষে পুরোনো অজগর জন্য ব্যাক-পোর্ট গ্রন্থাগার যোগ করুন, install_requires=[" importlib_resources ; python_version<'3.7'"](পরীক্ষা এই যদি আপনার সাথে আপনার প্রকল্পের প্যাকেজ setuptools<36.2.1)।
  • যদি আপনি theতিহ্যগত পদ্ধতি থেকে স্থানান্তরিত হন তবে setuptoolsআপনার রানটাইম-প্রয়োজনীয়তা থেকে গ্রন্থাগারটি সরিয়ে ফেলতে ভুলবেন না।
  • কাস্টমাইজ করতে setup.pyবা কোনও স্থিতিশীল ফাইল অন্তর্ভুক্তMANIFEST করতে ভুলবেন না ।
  • এছাড়াও আপনি সেট করতে পারেন zip_safe=Trueআপনার setup.py

4
str.join সিকোয়েন্স রিসোর্স_পথ = '/'.জয়েনউ((' টিম্পলেটস ',' অস্থায়ী_ফায়াল ') নেয়)
অ্যালেক্স পুন্নেন

4
আমি NotImplementedError: Can't perform this operation for loaders without 'get_data()'কোন ধারণা পেতে রাখা ?
লিওসেট

মনে রাখবেন যে, importlib.resourcesএবং pkg_resourcesহয় অগত্যা সামঞ্জস্যপূর্ণ নয়importlib.resourcesজিপফাইলে যোগ করা sys.path, সেটআপলগুলিতে pkg_resourcesকাজ করে এবং ডিমের ফাইলগুলির সাথে কাজ করে, যা নিজেই যুক্ত হওয়া ডিরেক্টরিতে জিপ ফাইলগুলি সঞ্চিত হয় sys.path। যেমন sys.path = [..., '.../foo', '.../bar.zip'], ডিমগুলি প্রবেশ করে .../fooতবে প্যাকেজগুলিও bar.zipআমদানি করা যায়। আপনি pkg_resourcesপ্যাকেজগুলি থেকে ডেটা আহরণ করতে ব্যবহার করতে পারবেন না bar.zipimportlib.resourcesডিমের সাথে কাজ করার জন্য সেটআপলগুলি প্রয়োজনীয় লোডারটি নিবন্ধন করে কিনা তা আমি পরীক্ষা করে দেখিনি ।
মার্টিজন পিটারস

4
ত্রুটি Package has no locationদেখা দিলে অতিরিক্ত সেটআপ.পিপি কনফিগারেশন প্রয়োজন ?
zygimantus

4
আপনি যদি বর্তমান মডিউলের অভ্যন্তরে কোনও ফাইল অ্যাক্সেস করতে চান (এবং templatesউদাহরণ অনুসারে সাব-মডিউল নয় ) তবে আপনি packageযুক্তিটি সেট করতে পারেন __package__, উদাহরণস্বরূপpkg_resources.read_text(__package__, 'temp_file')
বেন ম্যারেস

53

একটি প্যাকেজিং উপস্থাপক:

আপনি রিসোর্স ফাইলগুলি পড়ার বিষয়েও চিন্তাভাবনা করার আগে, প্রথম পদক্ষেপটি নিশ্চিত করা হয় যে ডেটা ফাইলগুলি প্রথমবারে আপনার বিতরণে প্যাকেজ হয়ে আসছে - সোর্স ট্রি থেকে তাদের সরাসরি পড়া সহজ, তবে গুরুত্বপূর্ণ অংশটি তৈরি করছে নিশ্চিত করুন যে এই সংস্থান ফাইলগুলি কোনও ইনস্টল করা প্যাকেজের মধ্যে কোড থেকে অ্যাক্সেসযোগ্য ।

প্যাকেজটির মধ্যে উপ-ডিরেক্টরিতে ডেটা ফাইল স্থাপন করে আপনার প্রকল্পটিকে এভাবে গঠন করুন :

.
├── 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

প্যাকেজিংয়ের বাইরে এখন পড়ার অংশে ...

প্রস্তাবনা:

স্ট্যান্ডার্ড গ্রন্থাগার pkgutilAPI গুলি ব্যবহার করুন । এটি লাইব্রেরি কোডে এর মতো দেখতে যাচ্ছে:

# within package/mymodule1.py, for example
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 দেখুন ।


4
এটি গত মে মাসে সম্পাদিত হয়েছে। তবে আমি অনুমান করি যে ইন্ট্রোতে ব্যাখ্যাগুলি সহজেই মিস করা যায়। তবুও, আপনি লোকদের স্ট্যান্ডার্ডের বিরুদ্ধে পরামর্শ দিন - এটি কামড়ানোর জন্য একটি শক্ত বুলেট :-)
অ্যাঙ্কোস্টিস

4
@ankostis এর পরিবর্তে আমাকে আপনার দিকে প্রশ্ন ঘুরিয়ে দিন, importlib.resourcesইতিমধ্যে অবমূল্যায়ন মুলতুবি থাকা একটি অসম্পূর্ণ এপিআই দিয়ে এই সমস্ত ত্রুটি থাকা সত্ত্বেও আপনি কেন সুপারিশ করবেন ? নতুন আরও ভাল হয় না। আমাকে বলুন এটি আসলে স্টাডলিব পিকগিলের উপর কী কী সুবিধা দেয় যা আপনার উত্তর সম্পর্কে কোনও উল্লেখ করা যায় না?
wim

4
প্রিয় @ উইম, ব্রেট ক্যাননেরpkgutil.get_data() আমার অন্ত্র অনুভূতির বিষয়টি নিশ্চিত করার বিষয়ে সর্বশেষ প্রতিক্রিয়া - এটি একটি অনুন্নত, থেকে-অবহিত এপিআই। এটি বলেছিল, আমি আপনার সাথে একমত, importlib.resourcesএটি আরও ভাল বিকল্প নয়, তবে PY3.10 এর সমাধান না হওয়া পর্যন্ত আমি এই পছন্দটির পাশে দাঁড়িয়েছি, হিভিং শিখেছে যে এটি ডক্স দ্বারা প্রস্তাবিত অন্য একটি "স্ট্যান্ডার্ড" নয়।
ankostis

4
@ আনকোস্টিস আমি ব্রেটের মন্তব্যগুলিতে নুনের দানা নিয়ে যাব। পিইপি 594pkgutil এর অবচয় সময়সূচীতে মোটেও উল্লেখ করা হয়নি - স্ট্যান্ডার্ড লাইব্রেরি থেকে মৃত ব্যাটারি অপসারণ এবং কোনও ভাল কারণ ছাড়াই অপসারণের সম্ভাবনা নেই is পাইথন ২.৩ থেকে এটি প্রায় হয়েছে এবং পিইপি 302- এ লোডার প্রোটোকলের অংশ হিসাবে নির্দিষ্ট করা হয়েছে । "আন্ডার-ডিফাইন্ড এপিআই" ব্যবহার করা খুব দৃ conv়প্রত্যয়ী উত্তর নয়, এটি পাইথন স্ট্যান্ডার্ড লাইব্রেরির বেশিরভাগ অংশকে বর্ণনা করতে পারে!
wim

4
আমাকে যুক্ত করতে দাও: আমিও আমদানি সংস্থানগুলি সফল হতে দেখতে চাই! আমি সমস্ত কঠোরভাবে সংজ্ঞায়িত API এর জন্য আছি। এটি কেবল তার বর্তমান অবস্থায় এটির পক্ষে সত্যই সুপারিশ করা যায় না। এপিআই এখনও পরিবর্তন চলছে, এটি প্রচুর বিদ্যমান প্যাকেজগুলির জন্য অপব্যবহারযোগ্য এবং কেবল অপেক্ষাকৃত সাম্প্রতিক পাইথন রিলিজগুলিতে উপলভ্য। বাস্তবে এটি pkgutilপ্রতিটি দিকের চেয়ে খারাপ । আপনার "অন্ত্র অনুভূতি" এবং কর্তৃত্বের কাছে আবেদন আমার কাছে অর্থহীন, যদি get_dataলোডারগুলির সাথে সমস্যা হয় তবে প্রমাণ এবং ব্যবহারিক উদাহরণগুলি দেখান।
wim

14

আপনি যদি এই কাঠামো আছে

lidtk
├── bin
│   └── lidtk
├── lidtk
│   ├── analysis
│   │   ├── char_distribution.py
│   │   └── create_cm.py
│   ├── classifiers
│   │   ├── char_dist_metric_train_test.py
│   │   ├── char_features.py
│   │   ├── cld2
│   │   │   ├── cld2_preds.txt
│   │   │   └── cld2wili.py
│   │   ├── get_cld2.py
│   │   ├── text_cat
│   │   │   ├── __init__.py
│   │   │   ├── README.md   <---------- say you want to get this
│   │   │   └── textcat_ngram.py
│   │   └── tfidf_features.py
│   ├── data
│   │   ├── __init__.py
│   │   ├── create_ml_dataset.py
│   │   ├── download_documents.py
│   │   ├── language_utils.py
│   │   ├── pickle_to_txt.py
│   │   └── wili.py
│   ├── __init__.py
│   ├── get_predictions.py
│   ├── languages.csv
│   └── utils.py
├── README.md
├── setup.cfg
└── setup.py

আপনার এই কোডটি দরকার:

import pkg_resources

# __name__ in case you're within the package
# - otherwise it would be 'lidtk' in this example as it is the package name
path = 'classifiers/text_cat/README.md'  # always use slash
filepath = pkg_resources.resource_filename(__name__, path)

অদ্ভুত "সর্বদা ব্যবহার স্ল্যাশ" অংশটি setuptoolsAPI গুলি থেকে আসে

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

আপনি যদি ডকুমেন্টেশনটি কোথায় আশ্চর্য হন:


আপনার সংক্ষিপ্ত উত্তরের জন্য ধন্যবাদ
পাওলো

pkg_resourcesওভারহেড আছে যে pkgutilপরাভূত। এছাড়াও, যদি প্রদত্ত কোডটি এন্ট্রি পয়েন্ট হিসাবে চালিত হয় তবে প্যাকেজের নাম নয়, __name__মূল্যায়ন করবে __main__
এ হেন্ড্রি

10

পাইথন কুকবুকের "১০.৮। ডেটাফাইলে প্যাকেজ ইন প্যাকেজ" পঠন, ডেভিড বেজলি এবং ব্রায়ান কে জোনসের তৃতীয় সংস্করণ।

আমি এটি এখানে পৌঁছে দেব:

ধরুন আপনার সাথে ফাইলগুলি সমন্বিত একটি প্যাকেজ রয়েছে যা নিম্নরূপ:

mypackage/
    __init__.py
    somedata.dat
    spam.py

এখন ধরা যাক স্প্যাম.পি ফাইলটি সোমদাটা.ড্যাট ফাইলটির বিষয়বস্তু পড়তে চায়। এটি করতে, নিম্নলিখিত কোডটি ব্যবহার করুন:

import pkgutil
data = pkgutil.get_data(__package__, 'somedata.dat')

ফলস্বরূপ ভেরিয়েবল ডেটা ফাইলের কাঁচামাল সম্বলিত একটি বাইট স্ট্রিং হবে।

Get_data () এর প্রথম যুক্তি প্যাকেজের নাম সম্বলিত একটি স্ট্রিং। আপনি এটি সরাসরি সরবরাহ করতে পারেন বা একটি বিশেষ ভেরিয়েবল ব্যবহার করতে পারেন, যেমন __package__। দ্বিতীয় যুক্তি হ'ল প্যাকেজের মধ্যে থাকা ফাইলটির আপেক্ষিক নাম। যদি প্রয়োজন হয়, আপনি প্যাকেজের মধ্যে চূড়ান্ত ডিরেক্টরিটি অবস্থিত না হওয়া অবধি স্ট্যান্ডার্ড ইউনিক্স ফাইল নাম কনভেনশন ব্যবহার করে বিভিন্ন ডিরেক্টরিতে নেভিগেট করতে পারেন।

এইভাবে, প্যাকেজটি ডিরেক্টরি, .zip বা .egg হিসাবে ইনস্টল করতে পারে।


আমি পছন্দ করি আপনি কুকবুক রেফারেন্স!
এ হেন্ডরি

-1

আপনার প্যাকেজের প্রতিটি অজগর মডিউলের একটি __file__বৈশিষ্ট্য রয়েছে

আপনি এটি হিসাবে ব্যবহার করতে পারেন:

import os 
from mypackage

templates_dir = os.path.join(os.path.dirname(mypackage.__file__), 'templates')
template_file = os.path.join(templates_dir, 'template.txt')

ডিমের সংস্থানগুলির জন্য দেখুন: http : //peak.te temmune.com/DevCenter/PythonEggs#accessing-package-resources


4
এটি জিপ ফাইলগুলিতে থাকা উত্স কোডের জন্য কাজ করবে না।
এ হেন্ড্রি

-1

গৃহীত উত্তরটি ব্যবহার করা উচিত importlib.resourcespkgutil.get_dataএছাড়াও আর্গুমেন্টটির packageএকটি নামবিহীন স্থান প্যাকেজ হতে হবে ( pkgutil ডক্স দেখুন )। সুতরাং, সংস্থানটি সম্বলিত ডিরেক্টরিটিতে অবশ্যই একটি __init__.pyফাইল থাকতে হবে, এতে একেবারে একই সীমাবদ্ধতা রয়েছে importlib.resources। যদি ওভারহেড ইস্যুটি pkg_resourcesউদ্বেগের বিষয় না হয় তবে এটি একটি গ্রহণযোগ্য বিকল্পও।

Pre-Python-3.3সমস্ত প্যাকেজগুলির একটি থাকা প্রয়োজন __init__.py। প্যাকেজ হতে Post-Python-3.3কোনও ফোল্ডারের দরকার হয় না __init__.py। একে বলা হয় অ namespace package। দুর্ভাগ্যক্রমে, ( pkgutil ডক্স দেখুন ) এর pkgutilসাথে কাজ করে না ।namespace packages

উদাহরণস্বরূপ, প্যাকেজ কাঠামো সহ:

+-- foo/
|   +-- __init__.py
|   +-- bar/
|   |   +-- hi.txt

যেখানে hi.txtসবে আছে Hi!, আপনি নিম্নলিখিত পাবেন

>>> import pkgutil
>>> rsrc = pkgutil.get_data("foo.bar", "hi.txt")
>>> print(rsrc)
None

যাইহোক, একটি __init__.pyইন সঙ্গে bar, আপনি পাবেন

>>> import pkgutil
>>> rsrc = pkgutil.get_data("foo.bar", "hi.txt")
>>> print(rsrc)
b'Hi!'

এই উত্তরটি ভুল - সংস্থান সম্বলিত ডিরেক্টরিটির প্যাকেজ হওয়ার দরকার নেই। এটি একটি প্যাকেজের মধ্যে একটি উপ-ডিরেক্টরি হতে পারে । যার সীমাবদ্ধতা নেই importlib.resources, তা pkgutilহ'ল সংস্থানসমূহের নিজস্ব সংস্থান থাকা ডিরেক্টরিটিও __init__.pyখুব বেশি হওয়া দরকার, অর্থাত এটি একটি সাবপ্যাকেজ হতে হবে । এটি নামস্থান প্যাকেজ সমস্যাগুলির সাথে সম্পর্কিত নয়, যা প্যাকেজের __init__.pyমধ্যে ডেটা উপ-ডিরেক্টরিগুলির পরিবর্তে শীর্ষ স্তরের ডিরেক্টরিতে আছে কিনা তা উদ্বেগ করে ।
Wim

@ উইম আমি দুঃখিত, তবে আমি বিশ্বাস করি আপনি ভুল করেছেন। pre-Python 3.3+সমস্ত প্যাকেজ __init__.pyলোড করার প্রয়োজন ছিল। ৩.৩-এর পরে প্যাকেজগুলির প্রয়োজন নেই। ছাড়া প্যাকেজগুলি __init__.pyহয় namespace packages। প্রতি pkgutilডক্স, যদি আপনি একটি নামস্থান প্যাকেজ থেকে একটি সম্পদ লোড করার চেষ্টা করুন, আপনি পাবেন None। আমার আপডেট সম্পাদিত উত্তর দেখুন দয়া করে।
এ হেন্ড্রি

আপনি pkgutilভুলভাবে ব্যবহার করছিলেন। চেষ্টা করুনpkgutil.get_data("foo", "bar/hi.txt")
wim

-3

ধরে নিচ্ছি আপনি একটি ডিমের ফাইল ব্যবহার করছেন; নিষ্কাশন করা হয়নি:

আমি একটি সাম্প্রতিক প্রকল্পে এটি "সমাধান" করেছি, একটি পোস্ট-ইনস্টল স্ক্রিপ্ট ব্যবহার করে, যা ডিম (জিপ ফাইল) থেকে ফাইল সিস্টেমে সঠিক ডিরেক্টরিতে আমার টেমপ্লেটগুলি বের করে। এটি আমি খুঁজে পেয়েছি দ্রুততম, সবচেয়ে নির্ভরযোগ্য সমাধান, যেহেতু কাজ করা __path__[0]কখনও কখনও ভুল হতে পারে (আমি নামটি মনে করি না, তবে আমি অন্তত একটি লাইব্রেরি জুড়ে ক্যামেছি, যা সেই তালিকার সামনে কিছু যুক্ত করেছে!)।

এছাড়াও ডিমের ফাইলগুলি সাধারণত "ডিম ক্যাশে" নামে একটি অস্থায়ী স্থানে ফ্লাইতে উত্তোলন করা হয়। আপনি আপনার স্ক্রিপ্ট শুরু করার আগে বা তারপরেও, যেমন পরিবেশের পরিবর্তনশীল ব্যবহার করে সেই অবস্থানটি পরিবর্তন করতে পারেন eg

os.environ['PYTHON_EGG_CACHE'] = path

তবে এখানে পিকেজি_সোর্স রয়েছে যা কাজটি সঠিকভাবে করতে পারে।

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