16

Perl 允许我__DATA__在脚本中使用标记来标记数据块的开始。我可以使用 DATA 文件句柄读取数据。在脚本中存储数据块的 Pythonic 方式是什么?

4

4 回答 4

11

这取决于您的数据,但 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.
"""
于 2011-08-04T14:07:51.297 回答
6

使用 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更合适。)

于 2011-08-04T14:33:40.180 回答
1

IMO 它在很大程度上取决于数据的类型:如果您只有文本并且可以确定里面没有任何可能的 ''' 或 """,您可以使用此版本的存储文本。但是什么例如,如果您想要存储一些已知“”或“””存在或可能存在的文本?那么建议

  • 以任何方式存储编码的数据或
  • 把它放在一个单独的文件中

示例:文本是

Python 库中有很多 ''' 和 """。

在这种情况下,可能很难通过三引号来实现。所以你可以做

__DATA__ = """There are many '''s and \"""s in Python libraries.""";
print __DATA__

但是在编辑或替换文本时必须注意。在这种情况下,这样做可能更有用

$ python -c 'import sys; print sys.stdin.read().encode("base64")'
There are many '''s and """s in Python libraries.<press Ctrl-D twice>

然后你得到

VGhlcmUgYXJlIG1hbnkgJycncyBhbmQgIiIicyBpbiBQeXRob24gbGlicmFyaWVzLg==

作为输出。把它放到你的脚本中,比如在

__DATA__ = 'VGhlcmUgYXJlIG1hbnkgJycncyBhbmQgIiIicyBpbiBQeXRob24gbGlicmFyaWVzLg=='.decode('base64')
print __DATA__

看看结果。

于 2011-08-05T15:15:30.160 回答
0

不熟悉 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的唯一用途是用于测试,那么您最好创建一个 doctest 或在 PyUnit / Nose 中编写一个测试用例。

例如:

import StringIO

def myfunc(lines):
    r"""Do something to each line

    Here's 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),但它无疑是一种测试代码的 Python 方法。

于 2011-08-04T14:35:35.463 回答