¿Cuál es la forma Pythonic de almacenar un bloque de datos en un script de Python?

Perl me permite usar el token __DATA__ en un script para marcar el inicio de un bloque de datos. Puedo leer los datos utilizando el identificador de archivo de datos. ¿Cuál es la forma Pythonic de almacenar un bloque de datos en un script?

Depende de sus datos, pero los literales dict y las cadenas multilínea son formas muy buenas.

 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. """ 

Use el módulo StringIO para crear un objeto tipo archivo en la fuente:

 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() 

Huellas dactilares:

 Now is the winter of our discontent, Made glorious summer by this sun of York. Now is the winter of our discontent, 

(Acabo de llamar a este __DATA__ para alinearlo con su pregunta original. En la práctica, esto no sería un buen estilo de nomenclatura de Python, algo como un datafile sería más apropiado).

No estar familiarizado con la variable __DATA__ de Perl, Google me está diciendo que a menudo se usa para pruebas. Suponiendo que también está buscando probar su código, es posible que desee considerar doctest (http://docs.python.org/library/doctest.html). Por ejemplo, en lugar de

 import StringIO __DATA__ = StringIO.StringIO("""lines of data from a file """) 

Suponiendo que quiere que DATA sea ​​un objeto de archivo, ahora es lo que tiene y que puede usarlo como la mayoría de los otros objetos de archivo en el futuro. Por ejemplo:

 if __name__=="__main__": # test myfunc with test data: lines = __DATA__.readlines() myfunc(lines) 

Pero si el único uso de DATA es para realizar pruebas, probablemente sea mejor crear un doctest o escribir un caso de prueba en PyUnit / Nose.

Por ejemplo:

 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() 

Ejecutando esas pruebas como esta:

 $ 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 hace muchas cosas diferentes, como encontrar pruebas de Python en archivos de texto sin formato y ejecutarlas. Personalmente, no soy un gran fanático y prefiero enfoques de prueba más estructurados ( import unittest ) pero es inequívocamente una forma pythonica de probar los códigos.

OMI depende en gran medida del tipo de datos: si solo tiene texto y puede estar seguro de que no hay “” o “” que pueden estar dentro, puede utilizar esta versión de almacenamiento del texto. para hacer si desea, por ejemplo, almacenar algún texto donde se sepa que ” ‘o “” “está ahí o podría estar allí? Entonces es aconsejable

  • o bien almacenar los datos codificados de cualquier manera o
  • ponlo en un archivo separado

Ejemplo: el texto es

Hay muchas ” ” s y “” “s en las bibliotecas de Python.

En este caso, puede ser difícil hacerlo a través de una cita triple. Para que puedas hacer

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

Pero hay que prestar atención al editar o reemplazar el texto. En este caso, podría ser más útil hacer

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

entonces obtienes

 VGhlcmUgYXJlIG1hbnkgJycncyBhbmQgIiIicyBpbiBQeXRob24gbGlicmFyaWVzLg== 

como salida Toma esto y ponlo en tu guión, como en

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

y ver el resultado.