Perl позволяет мне использовать токен __DATA__
в script, чтобы отметить начало блока данных. Я могу читать данные с помощью дескриптора файла DATA. Что такое питоновский способ хранения блока данных в script?
Что такое Pythonic способ хранения блока данных в Python script?
Ответ 1
Это зависит от ваших данных, но литералы dict и многострочные строки являются действительно хорошими способами.
state_abbr = {
'MA': 'Massachusetts',
'MI': 'Michigan',
'MS': 'Mississippi',
'MN': 'Minnesota',
'MO': 'Missouri',
}
gettysburg = """
Four score and seven years ago,
our fathers brought forth on this continent
a new nation,
conceived in liberty
and dedicated to the proposition
that all men are created equal.
"""
Ответ 2
Используйте модуль StringIO для создания файла с файлом в исходном файле:
from StringIO import StringIO
textdata = """\
Now is the winter of our discontent,
Made glorious summer by this sun of York.
"""
# in place of __DATA__ = open('richard3.txt')
__DATA__ = StringIO(textdata)
for d in __DATA__:
print d
__DATA__.seek(0)
print __DATA__.readline()
Печать
Now is the winter of our discontent,
Made glorious summer by this sun of York.
Now is the winter of our discontent,
(Я просто назвал этот __DATA__
совпадающим с вашим исходным вопросом. На практике это не будет хорошим стилем наименования Python - что-то вроде datafile
будет более подходящим.)
Ответ 3
Не знакомо с переменной Perl __DATA__
Google сообщает мне, что она часто используется для тестирования. Предполагая, что вы также изучаете свой код, вы можете захотеть рассмотреть doctest (http://docs.python.org/library/doctest.html). Например, вместо
import StringIO
__DATA__ = StringIO.StringIO("""lines
of data
from a file
""")
Предполагая, что вы хотите DATA быть файловым объектом, который теперь имеет то, что у вас есть, и вы можете использовать его, как и большинство других файловых объектов в будущем. Например:
if __name__=="__main__":
# test myfunc with test data:
lines = __DATA__.readlines()
myfunc(lines)
Но если для тестирования используется только DATA, вам, вероятно, лучше создать доктрину или написать тестовый пример в PyUnit/Nose.
Например:
import StringIO
def myfunc(lines):
r"""Do something to each line
Here an example:
>>> data = StringIO.StringIO("line 1\nline 2\n")
>>> myfunc(data)
['1', '2']
"""
return [line[-2] for line in lines]
if __name__ == "__main__":
import doctest
doctest.testmod()
Запуск таких тестов:
$ python ~/doctest_example.py -v
Trying:
data = StringIO.StringIO("line 1\nline 2\n")
Expecting nothing
ok
Trying:
myfunc(data)
Expecting:
['1', '2']
ok
1 items had no tests:
__main__
1 items passed all tests:
2 tests in __main__.myfunc
2 tests in 2 items.
2 passed and 0 failed.
Test passed.
Doctest делает много разных вещей, включая поиск тестов python в текстовых файлах и их запуск. Лично я не большой поклонник и предпочитаю более структурированные подходы к тестированию (import unittest
), но он однозначно является питоническим способом тестирования кода.
Ответ 4
IMO сильно зависит от типа данных: если у вас есть только текст и вы можете быть уверены, что не существует '' 'или' ", который, возможно, будет внутри, вы можете использовать эту версию хранения текста. Но что делать, если вы хотите, например, сохранить какой-то текст, где известно, что" или "" есть" или могут быть там? Тогда рекомендуется
- либо хранить кодированные данные каким-либо образом, либо
- поместите его в отдельный файл
Пример: текст
В библиотеках Python существует множество "и" и "s".
В этом случае это может быть трудно сделать с помощью тройной цитаты. Таким образом, вы можете сделать
__DATA__ = """There are many '' and \"""s in Python libraries.""";
print __DATA__
Но вы должны обратить внимание при редактировании или замене текста. В этом случае было бы более полезно сделать
$ python -c 'import sys; print sys.stdin.read().encode("base64")'
There are many '' and """s in Python libraries.<press Ctrl-D twice>
тогда вы получите
VGhlcmUgYXJlIG1hbnkgJycncyBhbmQgIiIicyBpbiBQeXRob24gbGlicmFyaWVzLg==
в качестве вывода. Возьмите это и поместите в свой script, например, в
__DATA__ = 'VGhlcmUgYXJlIG1hbnkgJycncyBhbmQgIiIicyBpbiBQeXRob24gbGlicmFyaWVzLg=='.decode('base64')
print __DATA__
и посмотрите результат.