Is there are Python equivalent of Perl's __DATA__ filehandle?
Asked Answered
O

2

15

In Perl I often read data in from the filehandle __DATA__ at the end of the script:

while (<DATA>) {
    chomp;
    say;
}
__DATA__
line1
line2 

I find this quicker for testing code etc than reading in a file, as it means I can edit its contents on the fly.

From the doc:

The __DATA__ token tells the perl compiler that the perl code for compilation is finished.

Everything after the __DATA__ token is available for reading via the filehandle FOOBAR::DATA, where FOOBAR is the name of the current package when the __DATA__ token is reached.

Is there an equivalent in Python? If not, can anybody suggest the most Python-ish way of achieving a similar thing?

Optimistic answered 14/7, 2016 at 8:17 Comment(2)
Could you explain what that actually does, for those of us better versed in Python than Perl?Froze
@jonrsharpe: it lets you add on data to the end of a module that can then be read as if it is a file.Gittern
G
13

No, there is no direct equivalent in Python. Put your data in a multi-line variable:

DATA = '''\
line1
line2
'''

You can then use DATA.splitlines() v2/v3 if you must have access to separate lines. You can put this at the end of your Python file provided you only use the name DATA in a function that is not called until after the whole module has loaded.

Alternatively, open the current module and read from that:

with open(__file__.rstrip('co')) as data:
    for line in data:
        while line != '# __DATA__\n':
            continue
        # do something with the rest of the 'data' in the current source file.

# ...

# __DATA__
# This is going to be read later on.

However the rest of the module must still at least be valid Python syntax; the Python parser can't be told to stop parsing beyond a given point.

Generally speaking, in Python you'd just put the data file next to your source files and read that. You can use the __file__ variable to produce a path the 'current directory' and thus to any other files in the same location:

import os.path

current_dir = os.path.dirname(os.path.abspath(__file__))
with open(os.path.join(current_dir, 'data.txt')) as data:
    # read from data.txt
Gittern answered 14/7, 2016 at 8:20 Comment(0)
G
0

A simple way to simulate Perl would be this:

import re

with open(__file__) as fp:
    for i in re.match(r'(?smx) .*? """\n __DATA__\n (.*)\n """\n', fp.read()).group(1).split("\n"):
        print(i)

"""
__DATA__
line1
line2 
"""
Grownup answered 29/7, 2022 at 4:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.