Eof python: EOF при чтении строки (Sublime Text 2 сердится) Ru Python

Содержание

EOF при чтении строки (Sublime Text 2 сердится) Ru Python

Это только в Sublime Text 2. Я попробовал IDLE, попробовал командную строку, все идеально. Почему Суллема кричит на меня?

Кстати, может быть, вы также можете объяснить, что может означать EOF в такой ситуации. Конечно, я прочитал в документации, что если EOF считывается с ввода, возникает соответствующая ошибка. Я хотел бы моделировать эту ситуацию. Вводится ли только о клавиатуре? Если да, какую комбинацию клавиш следует вводить для получения EOF?

Заранее спасибо.

У меня такая же проблема. Проблема с консолью по умолчанию Sublime Text заключается в том, что она не поддерживает ввод.

Чтобы решить эту проблему, вам необходимо установить пакет SublimeREPL. SublimeREPL предоставляет интерпретатор Python, который принимает ввод.

Существует статья , в которой подробно объясняется решение.

Страница GitHub для SublimeREPL

EOF – это специальный внеполосный сигнал, который означает конец ввода. Это не символ (хотя в старые DOS-дни, 0x1B действовал как EOF), а скорее сигнал от ОС, что вход закончился.

В Windows вы можете «ввести» EOF, нажав

Ctrl+Z в командной строке. Это сигнализирует терминалу о закрытии входного потока, который представляет EOF для текущей программы. Обратите внимание, что на других ОС или эмуляторах терминалов EOF обычно сигнализируется с помощью Ctrl+D

Что касается вашей проблемы с Sublime Text 2, кажется, что stdin не подключен к терминалу при запуске программы в Sublime, и поэтому программы начинают подключаться к пустым файлам (возможно, nul или /dev/null ). См. Также ошибку Python 3.1 и Sublime Text 2 .

help(input) показывает, какие сочетания клавиш производят EOF, а именно Unix: Ctrl-D , Windows: Ctrl-Z + Return :

input ([prompt]) -> string

Прочитайте строку со стандартного ввода.

Затянувшаяся новая строка лишена. Если пользователь нажимает EOF (Unix: Ctl-D, Windows: Ctl-Z + Return), поднимите EOFError. В Unix используется readline GNU, если включена. Строка подсказки, если она задана, перед чтением печатается без конечной новой строки.

Вы можете воспроизвести его с помощью пустого файла:

 $ touch empty $ python3 -c "input()" < empty Traceback (most recent call last): File "<string>", line 1, in <module> EOFError: EOF when reading a line 

Вы можете использовать /dev/null или nul (Windows) как пустой файл для чтения. os.devnull показывает имя, используемое вашей ОС:

 $ python3 -c "import os; print(os.devnull)" /dev/null 

Примечание: input() радостью принимает входные данные из файла / трубы. Вам не нужен

stdin для подключения к терминалу:

 $ echo abc | python3 -c "print(input()[::-1])" cba 

Либо дескриптор EOFError в вашем коде:

 try: reply = input('Enter text') except EOFError: break 

Или настройте свой редактор для предоставления непустого ввода, когда он запускает ваш скрипт, например, используя настраиваемую командную строку, если это разрешено: python3 "%f" < input_file

Похоже, единственное решение по-прежнему заключается в установке SublimeREPL.

Чтобы продлить ответ Рагхава, может быть очень неприятно, что нужно каждый раз запускать скрипт со входом в команду Tools-> SublimeREPL-> Python-> Run, поэтому я разработал быструю привязку клавиш, которая может быть удобной :

Чтобы включить его, перейдите в «Настройки» – «Ключ-привязки» – «Пользователь» и скопируйте его там:

 [ {"keys":["ctrl+r"] , "caption": "SublimeREPL: Python - RUN current file", "command": "run_existing_window_command", "args": { "id": "repl_python_run", "file": "config/Python/Main. sublime-menu" } }, ] 

Естественно, вам просто нужно изменить аргумент «keys», чтобы изменить ярлык на все, что вам нужно.

 try: value = raw_input() do_stuff(value) # next line was found except (EOFError): break #end of file reached 

Это, по-видимому, правильное использование raw_input при работе с концом потока ввода с входного канала. [Refer this post] [1]

Какой идеальный аналог в Python для «while not eof» Ru Python

Чтобы прочитать некоторый текстовый файл, в C или Pascal, я всегда использую следующие фрагменты для чтения данных до EOF:

Таким образом, мне интересно, как я могу сделать это просто и быстро в Python?

Прокрутите файл, чтобы прочитать строки:

 with open('somefile') as openfileobject: for line in openfileobject: do_something() 

Объекты файлов итерабельны и выводятся строки до EOF. Использование файлового объекта в качестве итерабельного использует буфер для обеспечения чтения результатов.

Вы можете сделать то же самое с stdin (нет необходимости использовать raw_input() :

 import sys for line in sys.stdin: do_something() 

Чтобы завершить изображение, бинарные чтения могут быть выполнены с помощью:

 from functools import partial with open('somefile', 'rb') as openfileobject: for chunk in iter(partial(openfileobject.read, 1024), ''): do_something()

где chunk будет содержать до 1024 байт за раз из файла.

Вы можете подражать C-идиоме в Python.

Чтобы прочитать буфер до max_size количество байтов, вы можете сделать это:

 with open(filename,'rb') as f: while True: buf=f.read(max_size) if not buf: break process(buf) 

Или текстовый файл по строкам:

 # warning -- not idiomatic Python! See below... with open(filename,'rb') as f: while True: line=f. readline() if not line: break process(line) 

Вы должны использовать в while True / break построить, поскольку нет теста eof в Python, кроме отсутствия байтов, возвращаемых из чтения.

В C вы можете иметь:

 while ((ch != '\n') && (ch != EOF)){ // read the next ch and add to a buffer // .. } 

Однако вы не можете иметь это в Python:

  while(line=f.readline()): # syntax error в  while(line=f.readline()): # syntax error 

потому что присваивания не допускаются в выражениях в Python.

Для Python это, безусловно, более идиоматично:

 # THIS IS IDIOMATIC Python. Do this: with open('somefile') as f: for line in f: process(line) 

Идиома Python для открытия файла и чтения строки за строкой:

 with open('filename') as f: for line in f: do_something(line) 

Файл будет автоматически закрыт в конце вышеуказанного кода ( with конструкцией позаботится об этом).

Наконец, стоит отметить, что line сохранит конечную новую

line . Это можно легко удалить, используя:

 line = line.rstrip() 

Хотя есть предложения, приведенные выше для того, чтобы «сделать это способом python», если у вас действительно есть логика на основе EOF, я полагаю, что использование обработки исключений – это способ сделать это –

 try: line = raw_input() ... whatever needs to be done incase of no EOF ... except EOFError: ... whatever needs to be done incase of EOF ... 

Пример:

 $ echo test | python -c "while True: print raw_input()" test Traceback (most recent call last): File "<string>", line 1, in <module> EOFError: EOF when reading a line 

Или нажмите Ctrl-Z в raw_input() (Windows, Ctrl-Z Linux)

Вы можете использовать ниже фрагмент кода для чтения по строкам, до конца файла

 line = obj. readline() while(line != ''): # Do Something line = obj.readline() 

Вы можете использовать следующий фрагмент кода. readlines () читает во всем файле сразу и разбивает его по строке.

 line = obj.readlines() 

python — EOF во время ввода: SyntaxError: unexpected EOF while parsing

Сообщение об ошибке не показывает у вас скобки (), поэтому ошибка в input() функции. Можно убедиться в этом, если в отдельной строке вызвать input().

То что вы получили SyntaxError, вызывая input() функцию, указывает что вы запускаете код, используя Питон 2, а не Питон 3, не смотря на то что указано в метках вопроса. В Питоне 2,

input() сам по себе работает по аналогии с eval(raw_input()).

SyntaxError вы получаете потому что, чтобы создать кортеж из двух чисел, необходимо запятую указать. При этом скобки совсем не нужны, если вы не хотите создать пустой кортеж: ().

Вот минимальное изменение к вашему коду в вопросе, чтобы он «печатал кортеж из всех этих чисел» (но прежде чем использовать пример, читайте ниже «eval()—зло» раздел):

#!/usr/bin/env python2
print input("Enter 2 comma-separated numbers: ") 

или

#!/usr/bin/env python3
print(eval(input("Enter 2 comma-separated numbers: ")))

Если ввести:

2,16

то в ответ оба примера напечатают:

(2, 16)

Конечно, пользователь программы свободен указать __import__('os').remove('важный файл')

вместо чисел. Поэтому более безопасный способ: прочесть строку и распознать заданный формат ввода вручную, например:

#!/usr/bin/env python2
print tuple(map(int, raw_input("Enter 2 comma-separated numbers: ").split(',')))

Или

#!/usr/bin/env python3
print(tuple(map(int, input("Enter 2 comma-separated numbers: "). split(','))))

Результаты те же, что и для предыдущих примеров.

Принимая ввод с клавиатуры, следует ожидать ошибок ввода, поэтому хорошо ловить исключения и повторить попытку получить числа, напечатав информативное сообщение об ошибке. См. Asking the user for input until they give a valid response.

Модуль pexpect — Документация Python для сетевых инженеров 3.0

Модуль pexpect позволяет автоматизировать интерактивные подключения, такие как:

Примечание

Pexpect — это реализация expect на Python.

Для начала, модуль pexpect нужно установить:

Логика работы pexpect такая:

  • запускается какая-то программа
  • pexpect ожидает определенный вывод (приглашение, запрос пароля и подобное)
  • получив вывод, он отправляет команды/данные
  • последние два действия повторяются столько, сколько нужно

При этом сам pexpect не реализует различные утилиты, а использует уже готовые.

pexpect.spawn

Класс spawn позволяет взаимодействовать с вызванной программой, отправляя данные и ожидая ответ.

Например, таким образом можно инициировать соединение SSH:

In [5]: ssh = pexpect.spawn('ssh [email protected]')

После выполнения этой строки, подключение готово. Теперь необходимо указать какую строку ожидать. В данном случае, надо дождаться запроса о пароле:

In [6]: ssh.expect('[Pp]assword')
Out[6]: 0

Обратите внимание как описана строка, которую ожидает pexpect: [Pp]assword. Это регулярное выражение, которое описывает строку password или Password. То есть, методу expect можно передавать регулярное выражение как аргумент.

Метод expect вернул число 0 в результате работы. Это число указывает, что совпадение было найдено и что это элемент с индексом ноль. Индекс тут фигурирует из-за того, что expect можно передавать список строк. Например, можно передать список с двумя элементами:

In [7]: ssh = pexpect. spawn('ssh [email protected]')

In [8]: ssh.expect(['password', 'Password'])
Out[8]: 1

Обратите внимание, что теперь возвращается 1. Это значит, что совпадением было слово Password.

Теперь можно отправлять пароль. Для этого используется команда sendline:

In [9]: ssh.sendline('cisco')
Out[9]: 6

Команда sendline отправляет строку, автоматически добавляет к ней перевод строки на основе значения os.linesep, а затем возвращает число указывающее сколько байт было записано.

Примечание

В pexpect есть несколько вариантов отправки команд, не только sendline.

Для того чтобы попасть в режим enable цикл expect-sendline повторяется:

In [10]: ssh.expect('[>#]')
Out[10]: 0

In [11]: ssh.sendline('enable')
Out[11]: 7

In [12]: ssh.expect('[Pp]assword')
Out[12]: 0

In [13]: ssh.sendline('cisco')
Out[13]: 6

In [14]: ssh.expect('[>#]')
Out[14]: 0

Теперь можно отправлять команду:

In [15]: ssh.sendline('sh ip int br')
Out[15]: 13

После отправки команды, pexpect надо указать до какого момента считать вывод. Указываем, что считать надо до #:

In [16]: ssh.expect('#')
Out[16]: 0

Вывод команды находится в атрибуте before:

In [17]: ssh.before
Out[17]: b'sh ip int br\r\nInterface                  IP-Address      OK? Method Status                Protocol\r\nEthernet0/0                192.168.100.1   YES NVRAM  up                    up      \r\nEthernet0/1                192.168.200.1   YES NVRAM  up                    up      \r\nEthernet0/2                19.1.1.1        YES NVRAM  up                    up      \r\nEthernet0/3                192.168.230.1   YES NVRAM  up                    up      \r\nEthernet0/3.100            10.100.0.1      YES NVRAM  up                    up      \r\nEthernet0/3.200            10.200.0.1      YES NVRAM  up                    up      \r\nEthernet0/3.300            10.30.0.1       YES NVRAM  up                    up      \r\nR1'

Так как результат выводится в виде последовательности байтов, надо конвертировать ее в строку:

In [18]: show_output = ssh. before.decode('utf-8')

In [19]: print(show_output)
sh ip int br
Interface                  IP-Address      OK? Method Status                Protocol
Ethernet0/0                192.168.100.1   YES NVRAM  up                    up
Ethernet0/1                192.168.200.1   YES NVRAM  up                    up
Ethernet0/2                19.1.1.1        YES NVRAM  up                    up
Ethernet0/3                192.168.230.1   YES NVRAM  up                    up
Ethernet0/3.100            10.100.0.1      YES NVRAM  up                    up
Ethernet0/3.200            10.200.0.1      YES NVRAM  up                    up
Ethernet0/3.300            10.30.0.1       YES NVRAM  up                    up
R1

Завершается сессия вызовом метода close:

Специальные символы в shell

Pexpect не интерпретирует специальные символы shell, такие как >, |, *.

Для того, чтобы, например, команда ls -ls | grep SUMMARY отработала, нужно запустить shell таким образом:

In [1]: import pexpect

In [2]: p = pexpect.spawn('/bin/bash -c "ls -ls | grep pexpect"')

In [3]: p.expect(pexpect.EOF)
Out[3]: 0

In [4]: print(p.before)
b'4 -rw-r--r-- 1 vagrant vagrant 3203 Jul 14 07:15 1_pexpect.py\r\n'

In [5]: print(p.before.decode('utf-8'))
4 -rw-r--r-- 1 vagrant vagrant 3203 Jul 14 07:15 1_pexpect.py

pexpect.EOF

В предыдущем примере встретилось использование pexpect.EOF.

Примечание

EOF (end of file) — конец файла

Это специальное значение, которое позволяет отреагировать на завершение исполнения команды или сессии, которая была запущена в spawn.

При вызове команды ls -ls pexpect не получает интерактивный сеанс. Команда выполняется и всё, на этом завершается её работа.

Поэтому если запустить её и указать в expect приглашение, возникнет ошибка:

In [5]: p = pexpect.spawn('/bin/bash -c "ls -ls | grep SUMMARY"')

In [6]: p.expect('nattaur')
---------------------------------------------------------------------------
EOF                                       Traceback (most recent call last)
<ipython-input-9-9c71777698c2> in <module>()
----> 1 p. expect('nattaur')
...

Если передать в expect EOF, ошибки не будет.

Метод pexpect.expect

В pexpect.expect как шаблон может использоваться:

  • регулярное выражение
  • EOF — этот шаблон позволяет среагировать на исключение EOF
  • TIMEOUT — исключение timeout (по умолчанию значение timeout = 30 секунд)
  • compiled re

Еще одна очень полезная возможность pexpect.expect: можно передавать не одно значение, а список.

Например:

In [7]: p = pexpect.spawn('/bin/bash -c "ls -ls | grep netmiko"')

In [8]: p.expect(['py3_convert', pexpect.TIMEOUT, pexpect.EOF])
Out[8]: 2

Тут несколько важных моментов:

  • когда pexpect.expect вызывается со списком, можно указывать разные ожидаемые строки
  • кроме строк, можно указывать исключения
  • pexpect.expect возвращает номер элемента списка, который сработал
    • в данном случае номер 2, так как исключение EOF находится в списке под номером два
  • за счет такого формата можно делать ответвления в программе, в зависимости от того, с каким элементом было совпадение

Пример использования pexpect

Пример использования pexpect для подключения к оборудованию и передачи команды show (файл 1_pexpect.py):

import pexpect
import re
from pprint import pprint


def send_show_command(ip, username, password, enable, commands, prompt="#"):
    with pexpect.spawn(f"ssh {username}@{ip}", timeout=10, encoding="utf-8") as ssh:
        ssh.expect("[Pp]assword")
        ssh.sendline(password)
        enable_status = ssh.expect([">", "#"])
        if enable_status == 0:
            ssh.sendline("enable")
            ssh.expect("[Pp]assword")
            ssh.sendline(enable)
            ssh.expect(prompt)

        ssh.sendline("terminal length 0")
        ssh.expect(prompt)

        result = {}
        for command in commands:
            ssh.sendline(command)
            match = ssh.expect([prompt, pexpect. TIMEOUT, pexpect.EOF])
            if match == 1:
                print(
                    f"Символ {prompt} не найден в выводе. Полученный вывод записан в словарь"
                )
            if match == 2:
                print("Соединение разорвано со стороны сервера")
                return result
            else:
                output = ssh.before
                result[command] = output.replace("\r\n", "\n")
        return result


if __name__ == "__main__":
    devices = ["192.168.100.1", "192.168.100.2", "192.168.100.3"]
    commands = ["sh clock", "sh int desc"]
    for ip in devices:
        result = send_show_command(ip, "cisco", "cisco", "cisco", commands)
        pprint(result, width=120)

Эта часть функции отвечает за переход в режим enable:

enable_status = ssh.expect([">", "#"])
if enable_status == 0:
    ssh.sendline("enable")
    ssh.expect("[Pp]assword")
    ssh.sendline(enable)
    ssh.expect(prompt)

Если ssh.expect([">", "#"]) возвращает индекс 0, значит при подключении не было автоматического перехода в режим enable и его надо выполнить. Если возвращается индекс 1 — значит мы уже находимся в режиме enable, например, потому что на оборудовании настроено privilege 15.

Еще один интересный момент в функции:

for command in commands:
    ssh.sendline(command)
    match = ssh.expect([prompt, pexpect.TIMEOUT, pexpect.EOF])
    if match == 1:
        print(
            f"Символ {prompt} не найден в выводе. Полученный вывод записан в словарь"
        )
    if match == 2:
        print("Соединение разорвано со стороны сервера")
        return result
    else:
        output = ssh.before
        result[command] = output.replace("\r\n", "\n")
return result

Тут по очереди отправляются команды и expect ждет три варианта: приглашение, таймаут или EOF. Если метод expect не дождался #, будет возвращено значение 1 и в этом случае выводится сообщение, что символ не найден. При этом, и когда совпадение найдено и когда был таймаут, полученный вывод записывается в словарь. Таким образом можно увидеть, что было получено с устройства, даже если приглашение не найдено.

Вывод при запуске скрипта:

{'sh clock': 'sh clock\n*13:13:47.525 UTC Sun Jul 19 2020\n',
 'sh int desc': 'sh int desc\n'
                'Interface                      Status         Protocol Description\n'
                'Et0/0                          up             up       \n'
                'Et0/1                          up             up       \n'
                'Et0/2                          up             up       \n'
                'Et0/3                          up             up       \n'
                'Lo22                           up             up       \n'
                'Lo33                           up             up       \n'
                'Lo45                           up             up       \n'
                'Lo55                           up             up       \n'}
{'sh clock': 'sh clock\n*13:13:50.450 UTC Sun Jul 19 2020\n',
 'sh int desc': 'sh int desc\n'
                'Interface                      Status         Protocol Description\n'
                'Et0/0                          up             up       \n'
                'Et0/1                          up             up       \n'
                'Et0/2                          admin down     down     \n'
                'Et0/3                          admin down     down     \n'
                'Lo0                            up             up       \n'
                'Lo9                            up             up       \n'
                'Lo19                           up             up       \n'
                'Lo33                           up             up       \n'
                'Lo100                          up             up       \n'}
{'sh clock': 'sh clock\n*13:13:53.360 UTC Sun Jul 19 2020\n',
 'sh int desc': 'sh int desc\n'
                'Interface                      Status         Protocol Description\n'
                'Et0/0                          up             up       \n'
                'Et0/1                          up             up       \n'
                'Et0/2                          admin down     down     \n'
                'Et0/3                          admin down     down     \n'
                'Lo33                           up             up       \n'}

Работа с pexpect без отключения постраничного вывода команд

Иногда вывод команды сильно большой и его не получается полностью считать или оборудование не дает возможность отключить постраничный вывод. В этом случае необходим немного другой подход.

Примечание

Эта же задача будет повторяться и для других модулей этого раздела.

Пример использования pexpect для работы с постраничным выводом команд show (файл 1_pexpect_more.py):

import pexpect
import re
from pprint import pprint


def send_show_command(ip, username, password, enable, command, prompt="#"):
    with pexpect.spawn(f"ssh {username}@{ip}", timeout=10, encoding="utf-8") as ssh:
        ssh.expect("[Pp]assword")
        ssh.sendline(password)
        enable_status = ssh.expect([">", "#"])
        if enable_status == 0:
            ssh.sendline("enable")
            ssh.expect("[Pp]assword")
            ssh.sendline(enable)
            ssh.expect(prompt)

        ssh.sendline(command)
        output = ""

        while True:
            match = ssh.expect([prompt, "--More--", pexpect.TIMEOUT])
            page = ssh.before.replace("\r\n", "\n")
            page = re.sub(" +\x08+ +\x08+", "\n", page)
            output += page
            if match == 0:
                break
            elif match == 1:
                ssh.send(" ")
            else:
                print("Ошибка: timeout")
                break
        output = re.sub("\n +\n", "\n", output)
        return output


if __name__ == "__main__":
    devices = ["192.168.100.1", "192.168.100.2", "192.168.100.3"]
    for ip in devices:
        result = send_show_command(ip, "cisco", "cisco", "cisco", "sh run")
        with open(f"{ip}_result.txt", "w") as f:
            f.write(result)

Теперь после отправки команды, метод expect ждет еще один вариант --More-- — признак, что дальше идет еще одна страница. Так как заранее не известно сколько именно страниц будет в выводе, чтение выполняется в цикле while True. Цикл прерывается если встретилось приглашение # или в течение 10 секунд не появилось приглашение или --More--.

Если встретилось --More--, страницы еще не закончились и надо пролистнуть следующую. В Cisco для этого надо нажать пробел (без перевода строки). Поэтому тут используется метод send, а не sendline — sendline автоматически добавляет перевод строки.

Эта строка page = re.sub(" +\x08+ +\x08+", "\n", page) удаляет backspace символы, которые находятся вокруг --More-- чтобы они не попали в итоговый вывод.

python — Как отправить EOF на стандартный ввод в paramiko?

Я хотел бы выполнить какую-то программу через ssh и перенаправить ее ввод из файла. Поведение следующего кода:

channel.exec_command('cat')
with open('mumu', 'r') as f:
    text = f.read()
    nbytes = 0
    while nbytes < len(text):
        sent = channel.send(text[nbytes:])
        if sent == 0:
            break
        nbytes += sent

Должно быть эквивалентно (при условии аутентификации с открытым ключом):

 ssh [email protected] cat < mumu

Однако приложение зависает в ожидании большего ввода. Я думаю, что это происходит потому, что поток stdin никогда не закрывается. Как мне это сделать?

6

Alexandru 31 Мар 2010 в 19:36

3 ответа

Лучший ответ

Позвоните shutdown() (или shutdown_write()) на канале.

5

John Zwinck 6 Сен 2016 в 03:47

Вызовите метод: channel.shutdown_write().

4

Rafa 10 Мар 2015 в 14:19

Поскольку я не использовал канал явно, мне пришлось сделать это немного по-другому. Для тех, кто может найти это полезным:

client = paramiko.SSHClient()
connection = client.connect(hostname)
stdin, stdout, stderr = connection.exec_command('cat')
stdin.write('spam')
# Close the channel, this results in an EOF for `cat`.
stdin.channel.shutdown_write()
# stdout/stderr are readable.
print(stdout.read().decode())
print(stderr.read().decode())

0

siebz0r 15 Мар 2019 в 10:44

2554292

python — Pandas ParserError EOF символ при чтении нескольких файлов CSV в HDF5

Я понимаю, что это старый вопрос, но я хотел бы поделиться более подробной информацией о первопричине этой ошибки и о том, почему работает решение @Selah. 

Из строки документации csv.py:

    * quoting - controls when quotes should be generated by the writer.
    It can take on any of the following module constants:

    csv.QUOTE_MINIMAL means only when required, for example, when a
        field contains either the quotechar or the delimiter
    csv.QUOTE_ALL means that quotes are always placed around fields.
    csv.QUOTE_NONNUMERIC means that quotes are always placed around
        fields which do not parse as integers or floating point
        numbers.
    csv.QUOTE_NONE means that quotes are never placed around fields.

csv.QUOTE_MINIMAL является значением по умолчанию, а " является значением по умолчанию quotechar. Если где-то в вашем CSV-файле у вас есть кавычка, он будет анализироваться как строка до следующего появления кавычка. Если в вашем файле нечетное количество кавычек, последний не будет закрыт до достижения EOF (конец файла). Также помните, что все, что находится между кавычками, будет проанализировано как одна строка. Даже если есть много разрывов строк (которые, как ожидается, будут проанализированы как отдельные строки), все это помещается в одно поле таблицы. Таким образом, номер строки, который вы получаете в ошибке, может вводить в заблуждение. Для иллюстрации на примере рассмотрим это:

In[4]: import pandas as pd
  ...: from io import StringIO
  ...: test_csv = '''a,b,c
  ...: "d,e,f
  ...: g,h,i
  ...: "m,n,o
  ...: p,q,r
  ...: s,t,u
  ...: '''
  ...: 
In[5]: test = StringIO(test_csv)
In[6]: pd.read_csv(test)
Out[6]: 
                 a  b  c
0  d,e,f\ng,h,i\nm  n  o
1                p  q  r
2                s  t  u
In[7]: test_csv_2 = '''a,b,c
  ...: "d,e,f
  ...: g,h,i
  ...: "m,n,o
  ...: "p,q,r
  ...: s,t,u
  ...: '''
  ...: test_2 = StringIO(test_csv_2)
  ...: 
In[8]: pd.read_csv(test_2)
Traceback (most recent call last):
...
...
pandas.errors.ParserError: Error tokenizing data. C error: EOF inside string starting at line 2

Первая строка имеет 2 (четные) кавычки. Таким образом, каждый кавычка закрывается, и CSV анализируется без ошибки, хотя, вероятно, не то, что мы ожидали. Другая строка имеет 3 (нечетные) кавычки. Последний не закрыт, и EOF достигнут, следовательно, ошибка. Но строка 2, которую мы получаем в сообщении об ошибке, вводит в заблуждение. Мы ожидаем 4, но, поскольку все между первым и вторым кавычками анализируется как строка, наша строка "p,q,r фактически является второй.

Свойства BOF, EOF (ADO) — SQL Server

  • Чтение занимает 2 мин

В этой статье

  • BOF Указывает, что текущая запись находится перед первой записью в объекте набора записей .BOF Indicates that the current record position is before the first record in a Recordset object.

  • Конец файла Указывает, что текущее расположение записи находится после последней записи в объекте набора записей . EOF Indicates that the current record position is after the last record in a Recordset object.

Возвращаемое значениеReturn Value

Свойства BOF и EOF возвращают логические значения.The BOF and EOF properties return Boolean values.

RemarksRemarks

Используйте свойства BOF и EOF , чтобы определить, содержит ли объект набора записей записи или выходят за пределы объекта набора записей при переходе от записи к записи.Use the BOF and EOF properties to determine whether a Recordset object contains records or whether you have gone beyond the limits of a Recordset object when you move from record to record.

Свойство BOF возвращает значение true (-1), если текущая запись находится перед первой записью, и false (0), если текущая запись находится в положении или после первой записи.The BOF property returns True (-1) if the current record position is before the first record and False (0) if the current record position is on or after the first record.

Свойство EOF возвращает значение true , если текущее расположение записи находится после последней записи, и значение false , если текущая запись находится в положении ON или до последней записи.The EOF property returns True if the current record position is after the last record and False if the current record position is on or before the last record.

Если свойство BOF или EOF имеет значение true, текущая запись отсутствует.If either the BOF or EOF property is True, there is no current record.

При открытии объекта Recordset , не содержащего записей, свойства BOF и EOF устанавливаются в значение true (Дополнительные сведения об этом состоянии набора записей см. в свойстве RecordCount ).If you open a Recordset object containing no records, the BOF and EOF properties are set to True (see the RecordCount property for more information about this state of a Recordset). При открытии объекта набора записей , содержащего хотя бы одну запись, первая запись является текущей, а свойства BOF и EOFfalse.When you open a Recordset object that contains at least one record, the first record is the current record and the BOF and EOF properties are False.

Если удалить последнюю оставшуюся запись в объекте Recordset , то свойства BOF и EOF могут остаться ложными , пока вы не попытаетесь изменить расположение текущей записи.If you delete the last remaining record in the Recordset object, the BOF and EOF properties may remain False until you attempt to reposition the current record.

В этой таблице показано, какие методы Move разрешены с различными сочетаниями свойств BOF и EOF .This table shows which Move methods are allowed with different combinations of the BOF and EOF properties.

MoveFirstMoveFirst,

MoveLastMoveLast

MovePreviousMovePrevious,

Переместить < 0Move < 0

Переместить 0Move 0 МетодMoveNext,

Переместить > 0Move > 0

BOF = True, EOF— = falseBOF=True, EOF=False ДопускаетсяAllowed ErrorError ErrorError ДопускаетсяAllowed
BOF = False, EOF— = trueBOF=False, EOF=True РазрешеноAllowed РазрешеноAllowed ErrorError ErrorError
Оба значения trueBoth True ErrorError ErrorError ErrorError ErrorError
Оба значения falseBoth False РазрешеноAllowed РазрешеноAllowed РазрешеноAllowed РазрешеноAllowed

Разрешение метода Move не гарантирует, что метод сможет успешно обнаружить запись. Это только означает, что вызов указанного метода Move не приведет к ошибке.Allowing a Move method does not guarantee that the method will successfully locate a record; it only means that calling the specified Move method will not generate an error.

В следующей таблице показано, что происходит с параметрами свойства BOF и EOF при вызове различных методов Move , но не удается успешно найти запись.The following table shows what happens to the BOF and EOF property settings when you call various Move methods but are unable to successfully locate a record.

BOFBOF EOFEOF
MoveFirst, MoveLastMoveFirst, MoveLast Задайте значение trueSet to True Задайте значение trueSet to True
Переместить 0Move 0 Без изменения.No change Без изменения.No change
MovePrevious, Перемещение < 0MovePrevious, Move < 0 Задайте значение trueSet to True Без изменения.No change
MoveNext, Move > 0MoveNext, Move > 0 Без изменения.No change Задайте значение trueSet to True

ПрименениеApplies To

Объект Recordset (ADO)Recordset Object (ADO)

См. также:See Also

Пример свойств BOF, EOF и Bookmark (Visual Basic) BOF, EOF, and Bookmark Properties Example (VB)
Пример свойств BOF, EOF и Bookmark (Visual c++)BOF, EOF, and Bookmark Properties Example (VC++)

Чтение файлов с Python

Работа с сохраненными данными является основным знанием каждого профессионального программиста Python. С самого раннего выпуска как чтение, так и запись данных в файлы являются встроенными функциями Python. По сравнению с другими языками программирования, такими как C или Java, он довольно прост и требует всего несколько строк кода. Более того, для этого не нужно загружать дополнительный модуль.

Основы файлов в Python

Общие методы работы с файлами: open (), , чтобы открыть файл, seek (), , чтобы установить текущую позицию файла по заданному смещению, и close (), , чтобы закрыть файловый объект, когда вы сделано с его помощью.Метод open () возвращает дескриптор файла, представляющий файловый объект, который будет использоваться для доступа к файлу для чтения, записи или добавления.

При открытии файла для чтения Python должен точно знать, как файл должен быть открыт в системе. Доступны два режима доступа — чтение и чтение в двоичном режиме. Соответствующие используемые флаги: r и rb , и должны быть указаны при открытии файла с помощью встроенного метода open () .Первый режим включает интерпретацию специальных символов, таких как «CR» (возврат каретки) и «LF» (перевод строки), для обозначения разрывов строки, тогда как двоичный режим позволяет вам читать данные в необработанном режиме, где данные хранятся как без дальнейшей интерпретации.

После открытия файла метод open () вернет вам объект файла. Эти файловые объекты имеют такие методы, как read () , readline () , write () , tell () и seek () .Хотя некоторые файловые объекты (или файловые объекты) имеют больше методов, чем перечисленные здесь, они являются наиболее распространенными. Не все файловые объекты должны реализовывать все файловые методы.

Примеры

В этой статье мы объясним, как читать файлы с помощью Python, на примерах. Некоторые примеры включают чтение файла построчно, как фрагмент (определенное количество строк за раз) и чтение файла за один раз. Кроме того, мы покажем вам способ прочитать только определенную строку из файла без поиска по всему файлу.

Чтение файла построчно

Первый пример основан на двух языках программирования C и C ++. Это довольно просто: откройте файл с помощью метода open () , прочтите файл построчно с помощью метода readline () и выведите строку сразу после чтения. Здесь используется цикл while , который непрерывно читает из файла, пока метод readline () продолжает возвращать данные. В случае, если конец файла (EOF) достигается , в то время как цикл останавливается и файловый объект закрывается, освобождая ресурсы для использования другими программами.

  # определить имя файла для чтения
filename = "test.txt"

# открываем файл для чтения
filehandle = open (имя файла, 'r')
в то время как True:
    # читать одну строку
    строка = filehandle.readline ()
    если не строка:
        перемена
    печать (строка)

# закрываем указатель на этот файл
filehandle.close ()
  

Листинг 1

Как вы, возможно, заметили в листинге листинг 1 , мы явно открыли и закрыли файл (строки 5 и 14 соответственно).Хотя интерпретатор Python автоматически закрывает открытые файлы в конце выполнения программы Python, явное закрытие файла с помощью close () является хорошим стилем программирования, и о нем нельзя забывать.

В качестве улучшения в Python 2.3 был представлен удобный протокол итератора. Это позволяет упростить цикл readline следующим образом:

  # определить имя файла для чтения
filename = "test.txt"

для открытой строки (имя файла, 'r'):
    печать (строка)
  

Листинг 2

Здесь используется цикл для в сочетании с итератором в .Файл открывается в строке 4 из Листинга 2 . Текущая строка идентифицируется с помощью итератора в , читается из файла, и ее содержимое выводится на stdout в строке 5. Python покрывает открытие и закрытие файла для вас, когда он выходит за рамки. Хотя это неэффективно, это позволяет вам больше не иметь дело с дескрипторами файлов.

К сожалению, приведенный выше код менее явный и полагается на внутреннюю сборку мусора Python для обработки закрытия файла.Представленная в Python 2.5 команда with еще больше инкапсулирует весь процесс, а также обрабатывает открытие и закрытие файлов только один раз во всем блоке кода с ограниченной областью видимости. В листинге 3 показано, как использовать с командой .

  # определить имя файла для чтения
filename = "test.txt"

с open (filename, 'r') в качестве дескриптора файла:
    для строки в дескрипторе файла:
        печать (строка)
  

Листинг 3

Комбинация оператора с оператором и команды open () открывает файл только один раз (строка 4).В случае успеха выполняется цикл для , и содержимое строки печатается на stdout (строки 5 и 6).

Кроме того, использование с оператором имеет побочный эффект. Внутренне интерпретатор Python создает try , наконец, -блок для инкапсуляции чтения из файла. Листинг 4 показывает, что по сути происходит внутри Python с с блоками кода:

  попробуйте:
    filehandle = open (имя файла, 'r')
    # сделай что-нибудь
наконец-то:
    дескриптор файла.Закрыть()
  

Листинг 4

Чтение файла в виде фрагментов строк

До сих пор мы обрабатывали файл построчно. Это довольно медленно для больших файлов и может быть улучшено путем одновременного чтения нескольких строк. Для этого в игру вступает метод islice () из модуля itertools. Кроме того, он работает как итератор и возвращает фрагмент данных, состоящий из n строк. В конце файла результат может быть короче, и, наконец, вызов вернет пустой список.

  из itertools import islice

# определяем имя файла для чтения
filename = "test.txt"

# определяем количество строк для чтения
number_of_lines = 5

с open (filename, 'r') как input_file:
    lines_cache = islice (файл_входа, число_строков)
   
    для current_line в lines_cache:
        печать (текущая_строка)
  

Листинг 5

Чтение определенной строки из файла

Используя методы, показанные выше, мы также можем выполнять другие полезные действия, такие как чтение определенной строки из файла.Для этого мы используем счетчик и печатаем соответствующую строку, когда доходим до нее, просматривая файл.

  # определить имя файла для чтения
filename = "test.txt"

# определяем номер строки
line_number = 3

print ("строка% i% s:"% (номер_строки, имя файла))

с open (filename, 'r') в качестве дескриптора файла:
current_line = 1
    для строки в дескрипторе файла:
        если current_line == line_number:
            печать (строка)
            перемена
        current_line + = 1
  

Листинг 6

Листинг 6 должен быть простым для понимания, но он немного длиннее, чем в предыдущих примерах.Его можно сократить с помощью модуля linecache. Листинг 7 показывает, как упростить код с помощью метода getline () . Если запрошенный номер строки выпадает из диапазона допустимых строк в файле, тогда метод getline () вместо этого возвращает пустую строку.

  # import linecache module
импорт строчного кэша

# определяем имя файла для чтения
filename = "test.txt"

# define line_number
line_number = 3

# получить конкретную строку
line = linecache.getline (имя файла, номер_строки)
print ("строка% i из% s:"% (номер_строки, имя файла))
печать (строка)
  

Листинг 7

Чтение всего файла сразу

И последнее, но не менее важное, мы рассмотрим совершенно другой случай, чем в предыдущем примере — чтение всего файла за один раз. Имейте в виду, что в большинстве случаев на вашем компьютере должно быть достаточно места для чтения всего файла в память. В листинге 8 используется комбинация операторов с и метода read () .В этом случае мы будем использовать read () для загрузки содержимого файла в виде потока данных.

  # определить имя файла для чтения
filename = "test.txt"

с open (filename, 'r') в качестве дескриптора файла:
    filecontent = filehandle.read ()
    печать (содержимое файла)
  

Листинг 8

Python также предлагает метод readlines () , который аналогичен методу readline () из первого примера. В отличие от read () , содержимое файла хранится в списке, где каждая строка содержимого является элементом. Листинг 9 показывает, как получить доступ к этим данным:

  # определить имя файла для чтения
filename = "test.txt"

с open (filename, 'r') в качестве дескриптора файла:
    filecontent = filehandle.readlines ()
    для строки в содержании файла:
        печать (строка)
  

Листинг 9

Хотя readlines () будет читать содержимое из файла до тех пор, пока не достигнет EOF, имейте в виду, что вы также можете ограничить объем считываемого содержимого, указав параметр sizehint , который представляет собой количество байтов для чтения.

Заключение

Как обычно, существует более одного способа прочитать содержимое файла. По скорости все они более или менее относятся к одной категории. Что касается того, какое решение лучше всего подходит для вас, зависит от вашего конкретного варианта использования. Мы думаем, что очень полезно увидеть, что возможно, а затем выбрать наиболее подходящее решение.

Хотя Python значительно упрощает процесс чтения файлов, время от времени он все же может стать сложным, и в этом случае я бы рекомендовал вам взглянуть на официальную документацию Python для получения дополнительной информации.

Ресурсы

Благодарности

Автор благодарит Золеку Хатитонгве за поддержку при подготовке статьи.

Python: как читать и писать файлы

  1. Дом
  2. Python: как читать и писать файлы

(Спонсоры) Начните изучать Python с помощью DataCamp’s бесплатный вводный курс по Python.Изучите науку о данных, выполняя интерактивные задания по кодированию и просматривая видео опытных инструкторов. Начинай сейчас!