Python: как правильно использовать readline () и readlines () - PullRequest
0 голосов
/ 25 декабря 2018

Я создал скрипт на Python для случайного создания предложений, используя данные из Princeton English Wordnet, следуя диаграммам, предоставленным Gödel, Escher, Bach .При вызове python GEB.py создается список бессмысленных предложений на английском языке, таких как:

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

И сохраняет их в gibberish.txt.Этот скрипт отлично работает.

Другой скрипт (translator.py) принимает gibberish.txt и через Python-модуль py-googletrans пытается перевести эти случайные предложения на португальский:

from googletrans import Translator
import json

tradutor = Translator()

with open('data.json') as dataFile:
    data = json.load(dataFile)


def buscaLocal(keyword):
    if keyword in data:
        print(keyword + data[keyword])
    else:
        buscaAPI(keyword)


def buscaAPI(keyword):
    result = tradutor.translate(keyword, dest="pt")
    data.update({keyword: result.text})

    with open('data.json', 'w') as fp:
        json.dump(data, fp)

    print(keyword + result.text)


keyword = open('/home/user/gibberish.txt', 'r').readline()
buscaLocal(keyword)

В настоящее времявторой скрипт выводит только перевод первого предложения в gibberish.txt.Что-то вроде:

возрождающихся эстетических затрат.aumento de custos inestético.

Я пытался использовать readlines() вместо readline(), но получаю следующую ошибку:

Traceback (most recent call last):
  File "main.py", line 28, in <module>
    buscaLocal(keyword)
  File "main.py", line 11, in buscaLocal
    if keyword in data:
TypeError: unhashable type: 'list'

Я читал похожие вопросы об этой ошибкездесь, но мне не ясно, что я должен использовать, чтобы прочитать весь список предложений, содержащихся в gibberish.txt (новые предложения начинаются с новой строки).

Как я могу прочитать весь списокпредложений, содержащихся в gibberish.txt?Как мне адаптировать код в translator.py, чтобы добиться этого?Прошу прощения, если вопрос немного запутан, я могу отредактировать, если необходимо, я новичок в Python, и я был бы признателен, если бы кто-нибудь мог мне помочь.

Ответы [ 2 ]

0 голосов
/ 25 декабря 2018

Давайте начнем с того, что вы делаете с файловым объектом.Вы открываете файл, получаете из него одну строку, а затем не закрываете его.Лучший способ сделать это - обработать весь файл и затем закрыть его.Обычно это делается с помощью блока with, который закрывает файл, даже если возникает ошибка:

with open('gibberish.txt') as f:
    # do stuff to f

Помимо материальных преимуществ, это сделает интерфейс более понятным, поскольку f недлиннее одноразовый объект.У вас есть три простых варианта обработки всего файла:

  1. Используйте readline в цикле, поскольку он будет читать только одну строку за раз.Вам придется вручную удалить символы новой строки и завершить цикл при появлении '':

    while True:
        line = f.readline()
        if not line: break
        keyword = line.rstrip()
        buscaLocal(keyword)
    

    Этот цикл может принимать множество форм, одна из которых показана здесь.

  2. Используйте readlines, чтобы сразу прочитать все строки в файле в список строк:

    for line in f.readlines():
        keyword = line.rstrip()
        buscaLocal(keyword)
    

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

    Это подводит нас к третьему варианту.

  3. Файлы Python являются повторяемыми объектами.Вы можете иметь чистоту подхода readlines с экономией памяти readline:

    for line in f:
         buscaLocal(line.rstrip())
    

    , этот подход можно смоделировать с помощью readline с более загадочной формой next для созданияаналогичный итератор:

    for line in next(f.readline, ''):
         buscaLocal(line.rstrip())
    

В качестве побочного замечания я бы внес несколько изменений в ваши функции:

def buscaLocal(keyword):
    if keyword not in data:
        buscaAPI(keyword)
    print(keyword + data[keyword])

def buscaAPI(keyword):
    # Make your function do one thing. In this case, do a lookup.
    # Printing is not the task for this function.
    result = tradutor.translate(keyword, dest="pt")
    # No need to do a complicated update with a whole new
    # dict object when you can do a simple assignment.
    data[keyword] = result.text

...

# Avoid rewriting the file every time you get a new word.
# Do it once at the very end.
with open('data.json', 'w') as fp:
    json.dump(data, fp)
0 голосов
/ 25 декабря 2018

Если вы используете функцию readline(), вы должны помнить, что эта функция возвращает только строку, поэтому вы должны использовать цикл для прохождения всех строк в текстовых файлах.В случае использования readlines(), эта функция читает весь файл сразу, но возвращает каждую строку в списке.Тип данных списка не подлежит изменению и не может использоваться в качестве ключа в dict объекте, поэтому строка if keyword in data: выдает эту ошибку, так как keyword - это список всех строк.простой цикл for решит эту проблему.

text_lines = open('/home/user/gibberish.txt', 'r').readlines()
for line in text_lines:
     buscaLocal(line)

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

...