Как да използвам данни в package_data от изходния код?

В setup.py съм посочил package_data по този начин:

packages=['hermes'],
package_dir={'hermes': 'hermes'},
package_data={'hermes': ['templates/*.tpl']},

И структурата на моята директория е приблизително

hermes/
 |
 | docs/
 | ...
 | hermes/
    | 
    | __init__.py
    | code.py
    | templates
        |
        | python.tpl
 |
 | README
 | setup.py

Проблемът е, че трябва да използвам файлове от директорията шаблони в моя изходен код, за да мога да напиша код на python (този проект е генератор на анализатори). Изглежда не мога да разбера как правилно да включа и използвам тези файлове от моя код. Някакви идеи?


person Scott    schedule 05.05.2011    source източник


Отговори (1)


Стандартната функция get_data() на модула pkgutil ще изчисли пътя до вашите данни, относително към вашия пакет и извличане на данните за вас чрез какъвто и да е модул за зареждане на Python, използван за импортиране на пакета hermes:

import pkgutil
data = pkgutil.get_data('hermes', 'templates/python.tpl')

Разбира се, в определени случаи можете просто да прочетете вашите данни, използвайки път, изчислен от hermes.__file__, но ако планирате да разпространявате проекта си, имайте предвид, че той може да бъде инсталиран по различни начини на машината на крайния потребител: като обикновени файлове, разположени в компресиран egg archive и т.н. В последния случай вашият hermes модул ще бъде импортиран от Python с помощта на zipimporter, което ви пречи да направите нормален open(path).read():

>>> import hermes
>>> hermes.__loader__
<zipimporter object "/home/pat/.cascade/virt/foo/lib/python2.6/site-packages/foo-0.0.0-py2.6.egg">

Ако сте съгласни с добавянето на зависимост по време на изпълнение към кодовата база distribute, може да помислите да разгледате pkg_resources module, което може да ви даде същия резултат, но добавя други възможности.

import pkg_resources
data = pkg_resources.resource_string('hermes', 'templates/python.tpl')
person samplebias    schedule 05.05.2011
comment
може да се използва __name__ вместо директно посочване на име на модул, следователно data = pkg_resources.resource_string('hermes', 'templates/python.tpl') става data = pkg_resources.resource_string(__name__, 'templates/python.tpl') - person b1r3k; 17.09.2014
comment
моля, използвайте path = pkg_resources.resource_filename('hermes', 'templates/python.tpl'), ако просто искате да получите пътя на package_data, и го прочетете сами. - person user1024; 23.01.2021