সেটআপলগুলি: প্যাকেজ ডেটা ফোল্ডারের অবস্থান


98

আমি আমার পাইথন প্যাকেজ বিতরণ করতে সেটআপলগুলি ব্যবহার করি। এখন আমার অতিরিক্ত ডেটা ফাইলগুলি বিতরণ করা দরকার।

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

আমি যা এড়াতে চাই:

/ #root
|- src/
|  |- mypackage/
|  |  |- data/
|  |  |  |- resource1
|  |  |  |- [...]
|  |  |- __init__.py
|  |  |- [...]
|- setup.py

পরিবর্তে আমি কী পেতে চাই:

/ #root
|- data/
|  |- resource1
|  |- [...]
|- src/
|  |- mypackage/
|  |  |- __init__.py
|  |  |- [...]
|- setup.py

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


9
আমি 'data_files' ব্যবহার সম্পদগুলি (ডক্স, ছবি, ইত্যাদি) বিতরণ করা সম্পর্কে একটি অনুরূপ প্রশ্ন জিজ্ঞাসা: stackoverflow.com/questions/5192386/... ... এবং (দুই) প্রতিক্রিয়া উভয় 'package_data' ব্যবহার করতে পরিবর্তে বলেন। এখন আমি প্যাকেজ ডেটা ব্যবহার করছি, তবে এর অর্থ হল আমার প্যাকেজের ভিতরে আমার ডেটা এবং ডক্স রাখতে হবে, অর্থাত্ আমার উত্স কোডের মধ্যে মিশ্রিত। আমি এটি অপছন্দ করি। আমার উত্সটি গ্রিপ করার সময়, আমি যে শ্রেণীর সংজ্ঞাটি অনুসন্ধান করছি তা কেবল খুঁজে পাই না, তবে তারা আমার আরএসটি, এইচটিএমএল এবং মধ্যবর্তী ফাইলগুলির মধ্যে পাওয়া কয়েক ডজন উল্লেখ করে। :-(
জোনাথন হার্টলি

4
আমি জানি যে এই প্রতিক্রিয়াটি খুব দেরী হয়েছে, @ জোনাথন হার্টলি, তবে আপনি __init__.pyযে ফাইল ডিরেক্টরি ফাঁকা থাকলেও কোনও ফাইল যুক্ত করে কোনও ডিরেক্টরিকে "প্যাকেজ" বানাতে পারেন । সুতরাং আপনি __init__.pyকোনও প্যাকেজের মতো দেখতে এটি খালি ফাইলের সাথে ডেটা ডিরেক্টরি আলাদা রাখতে পারেন could এটি আপনার উত্স গাছের মধ্যে থেকে বাছাই করা থেকে গ্রেপ রাখা উচিত তবে এটি অজগর এবং এর বিল্ড সরঞ্জামগুলির দ্বারা এটি প্যাকেজ হিসাবে স্বীকৃত হবে।
dhj

@ ডিজেজে একটি আকর্ষণীয় ধারণা, ধন্যবাদ।
জোনাথন হার্টলি

4
@ ডিজেজে এই পদ্ধতির একমাত্র সমস্যা অজগর মনে করে আপনি 'ডেটা' নামে একটি প্যাকেজ ইনস্টল করেছেন। আপনার ইনস্টল করা অন্য প্যাকেজ যদি একইভাবে ডেটা প্যাকেজ করার চেষ্টা করে তবে আপনার দুটি বিতর্কিত 'ডেটা' প্যাকেজ ইনস্টল হবে।
পায়ের আঙ্গুল

উত্তর:


112

বিকল্প 1: প্যাকেজ ডেটা হিসাবে ইনস্টল করুন

আপনার পাইথন প্যাকেজটির মূলের অভ্যন্তরে ডেটা ফাইল রাখার প্রধান সুবিধাটি হ'ল এটি আপনাকে ব্যবহারকারীর সিস্টেমে ফাইলগুলি কোথায় বাস করবে তা ভেবে চিন্তিত এড়াতে দেয়, এটি উইন্ডোজ, ম্যাক, লিনাক্স, কোনও মোবাইল প্ল্যাটফর্ম বা কোনও ডিমের ভিতরে থাকতে পারে। dataআপনার পাইথন প্যাকেজ রুটের সাথে সম্পর্কিত ডিরেক্টরিটি আপনি সর্বদা খুঁজে পেতে পারেন, এটি কোথায় বা কীভাবে ইনস্টল করা হয়েছে তা বিবেচনা করে।

উদাহরণস্বরূপ, যদি আমার মতো প্রজেক্ট লেআউট থাকে:

project/
    foo/
        __init__.py
        data/
            resource1/
                foo.txt

আপনি __init__.pyএকটি ডেটা ফাইলের একটি নিখুঁত পথ সনাক্ত করতে একটি ফাংশন যুক্ত করতে পারেন :

import os

_ROOT = os.path.abspath(os.path.dirname(__file__))
def get_data(path):
    return os.path.join(_ROOT, 'data', path)

print get_data('resource1/foo.txt')

ফলাফল:

/Users/pat/project/foo/data/resource1/foo.txt

প্রকল্পটি ডিম হিসাবে ইনস্টল হওয়ার পরে পথটি dataপরিবর্তিত হবে তবে কোডটি পরিবর্তনের প্রয়োজন নেই:

/Users/pat/virtenv/foo/lib/python2.6/site-packages/foo-0.0.0-py2.6.egg/foo/data/resource1/foo.txt

বিকল্প 2: স্থির স্থানে ইনস্টল করুন

বিকল্পটি হ'ল পাইথন প্যাকেজের বাইরে আপনার ডেটা স্থাপন করা এবং তারপরে হয়:

  1. dataএকটি কনফিগারেশন ফাইল, কমান্ড লাইন আর্গুমেন্ট বা মাধ্যমে পাস করার অবস্থানটি রাখুন
  2. আপনার পাইথন কোডে অবস্থানটি এম্বেড করুন।

আপনি যদি আপনার প্রকল্পটি বিতরণের পরিকল্পনা করেন তবে এটি অনেক কম কাঙ্ক্ষিত। আপনি যদি সত্যিই এটি করতে চান তবে আপনি dataটার্গলগুলির তালিকায় পাস করে প্রতিটি গ্রুপের ফাইলের গন্তব্য নির্দিষ্ট করে টার্গেট সিস্টেমে আপনার পছন্দটি ইনস্টল করতে পারেন :

from setuptools import setup
setup(
    ...
    data_files=[
        ('/var/data1', ['data/foo.txt']),
        ('/var/data2', ['data/bar.txt'])
        ]
    )

আপডেট হয়েছে : পাইথন ফাইলগুলি পুনরাবৃত্তভাবে গ্রেপ করতে শেল ফাংশনের উদাহরণ:

atlas% function grep_py { find . -name '*.py' -exec grep -Hn $* {} \; }
atlas% grep_py ": \["
./setup.py:9:    package_data={'foo': ['data/resource1/foo.txt']}

7
আমাকে পরিস্থিতি শর্তে আসতে সাহায্য করার জন্য অনেক ধন্যবাদ। সুতরাং আপনার (এবং প্রত্যেকে) পরামর্শ হিসাবে প্যাকেজ_ডাটা ব্যবহার করে দৌড়াতে পেরে আমি আনন্দিত। তবে: কেবলমাত্র আমিই কে তাদের প্যাকেজ উত্স ডিরেক্টরিতে তাদের ডেটা এবং ডক্সগুলি অসুবিধাজনক হিসাবে খুঁজে পেয়েছি? (উদাহরণস্বরূপ, আমার উত্সটি গ্রিপিং করা আমার ডকুমেন্টেশন থেকে কয়েক ডজন অযাচিত হিট দেয় ' আমদানি না করেই আমার প্যাকেজ দিরের ভিতরে 'এসসিআর' সাবডির অন্তর্ভুক্ত করা যেমন সম্ভব
যোনাথন হার্টলি

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

আরে নমুনা। আপডেটের জন্য ধন্যবাদ। এটা ঠিক এটা যদিও grep না, সবকিছু awk করার ctags চাই, টেক্সট এডিটর অনুসন্ধান-ইন-ফাইল থেকে। আপনার প্রস্তাব অনুসারে আমি ডেটা_ফাইলে ডক্স রাখার জন্য আমার প্রকল্পটি পুনরায় সাজানোর চেষ্টা করতে যাচ্ছি, দেখুন কীভাবে এটি কার্যকর হয়। শীঘ্রই ফিরে ... :-)
জোনাথন হার্টলি

... এটা ঠিক আছে বলে মনে হচ্ছে। আমাকে সঠিক পথে রাখার জন্য ধন্যবাদ +50 খ্যাতি পয়েন্টগুলি কি সুস্বাদু?
জোনাথন হার্টলি

ধন্যবাদ! শুনে খুব ভালো লাগল, খুশী হ'ল এটি কার্যকর হয়েছে এবং আপনি উন্নতি করছেন!
স্যাম্পলবায়াস

14

আমি মনে করি যে আমি একটি ভাল সমঝোতা পেয়েছি যা আপনাকে নিম্নলিখিত কাঠামোকে মেন্টেন করার অনুমতি দেবে:

/ #root
|- data/
|  |- resource1
|  |- [...]
|- src/
|  |- mypackage/
|  |  |- __init__.py
|  |  |- [...]
|- setup.py

স্যাম্পেলবায়াস উত্তরে বর্ণিত সমস্যাগুলি এড়াতে আপনার প্যাকেজ_ডাটা হিসাবে ডেটা ইনস্টল করা উচিত, তবে ফাইলের কাঠামোটি মেন্টেন করার জন্য আপনার সেটআপে যোগ করা উচিত:

try:
    os.symlink('../../data', 'src/mypackage/data')
    setup(
        ...
        package_data = {'mypackage': ['data/*']}
        ...
    )
finally:
    os.unlink('src/mypackage/data')

এইভাবে আমরা "ঠিক সময়ে" উপযুক্ত কাঠামো তৈরি করি, এবং আমাদের উত্স ট্রিটি সুবিন্যস্ত করি।

আপনার কোডের মধ্যে এই জাতীয় ডেটা ফাইল অ্যাক্সেস করতে আপনি 'সহজ' ব্যবহার করুন:

data = resource_filename(Requirement.parse("main_package"), 'mypackage/data')

আমি এখনও কোডটিতে 'মাইপ্যাকেজ' নির্দিষ্ট করা পছন্দ করি না, কারণ এই মডিউলটির সাথে ডেটাটির অগত্যা কিছু করতে পারে না, তবে আমি এটি একটি ভাল আপসটি অনুমান করি।


-4

আমি মনে করি আপনি মূলত সেট আপ () সেট আপ করতে * ডেটা_ফায়ালস * হিসাবে আর্গুমেন্ট হিসাবে কিছু দিতে পারেন ।


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

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