Perl允许我在脚本中使用__DATA__
标记来标记数据块的开始。我可以使用DATA文件句柄读取数据。那么,在Python中如何以Pythonic的方式将数据块存储在脚本中呢?
Perl允许我在脚本中使用__DATA__
标记来标记数据块的开始。我可以使用DATA文件句柄读取数据。那么,在Python中如何以Pythonic的方式将数据块存储在脚本中呢?
取决于你的数据,但字典字面值和多行字符串都是非常好的方法。
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.
"""
str = "\x80abc"
可以工作,尽管它包含一个非法的 utf-8 码位,而 str = b"\x80abc".decode("utf-8")
则会可预测地失败。这是多么奇怪的行为啊。看起来结果只是被忽略了(就好像你将解码的错误模式设置为“忽略”一样)。 - Voob'\xc2\x80'
。b"\x80abc"
的问题在于它是一个无效的 UTF-8 序列,这是完全不同的问题。 - chepnerfrom 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
之类的东西。
在我看来,这高度取决于数据的类型:如果你只有文本,并且可以确定其中没有可能包含 ''' 或 """ 的情况,那么你可以使用这个版本来存储文本。但是如果你想要存储一些已知包含或可能包含 ''' 或 """ 的文本,该怎么办呢?那么建议:
例如:文本为
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__
然后查看结果。
不熟悉Perl的__DATA__
变量,谷歌告诉我它经常用于测试。假设您也正在研究测试代码,您可能需要考虑使用doctest(http://docs.python.org/library/doctest.html)。例如,不是
import StringIO
__DATA__ = StringIO.StringIO("""lines
of data
from a file
""")
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
),但毫无疑问,这是一种 Pythonic 的测试代码的方式。