Вы используете объект, содержащий ссылку нулевого значения. Таким образом, он дает пустое исключение. В примере строковое значение равно null, и при проверке его длины произошло исключение.
Пример:
string value = null;
if (value.Length == 0) // <-- Causes exception
{
Console.WriteLine(value); // <-- Never reached
}
Ошибка исключения:
Необработанное исключение:
System.NullReferenceException: ссылка на объект не установлена в экземпляр объекта. в Program.Main ()
blockquote>
Вариант 1: Установить как данные пакета
. Основное преимущество размещения файлов данных внутри корня вашего пакета Python заключается в том, что он позволяет вам не беспокоиться о том, где файлы будут жить в системе пользователя, что могут быть Windows, Mac, Linux, некоторые мобильные платформы или внутри Яйца. Вы всегда можете найти каталог data
относительно вашего корня пакета Python, независимо от того, где и как он установлен.
Например, если у меня есть макет проекта, например:
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: установить в фиксированное местоположение
альтернативой было бы размещение ваших данных вне пакета Python, а затем либо:
data
через файл конфигурации, аргументы командной строки или Это гораздо менее желательно, если вы планируете распространять свой проект. Если вы действительно хотите это сделать, вы можете установить data
везде, где захотите, в целевой системе, указав место назначения для каждой группы файлов, перейдя в список кортежей:
from setuptools import setup
setup(
...
data_files=[
('/var/data1', ['data/foo.txt']),
('/var/data2', ['data/bar.txt'])
]
)
Обновлено: Пример функции оболочки для рекурсивно grep файлов Python:
atlas% function grep_py { find . -name '*.py' -exec grep -Hn $* {} \; }
atlas% grep_py ": \["
./setup.py:9: package_data={'foo': ['data/resource1/foo.txt']}
Я использую setuptools для создания собственных пакетов ОС, таких как RPM и DEB. Я использую макет проекта.
<project>/
lib/ -> .../lib/pythonX/site-packages/
bin/ -> .../bin/
etc/ -> /etc/
doc/
man/ -> .../man/man1/
share/ -> .../share/doc/<project>/
Мой файл setup.py
выполняет соответствующее сопоставление, как указано выше. Я считаю, что этот макет идеален для python. Выпущенные пакеты переносятся, но по умолчанию будут находиться под /usr/local/
.
Я думаю, что вы можете в принципе дать что-нибудь как аргумент * data_files * в setup () .
Думаю, я нашел хороший компромисс, который позволит вам создать следующую структуру:
/ #root
|- data/
| |- resource1
| |- [...]
|- src/
| |- mypackage/
| | |- __init__.py
| | |- [...]
|- setup.py
Вы должны установить данные как package_data, чтобы избежать проблем, описанных в ответе samplebias, но для того, чтобы mantain структуру файла, которую вы должны добавить в свой 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')
Мне все еще не нравится указывать «mypackage» в коде, так как данные могут не иметь ничего общего с этим модулем, но я думаю, что это хороший компромисс.