简体   繁体   中英

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

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?

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM