Как написать список в файл с символами новой строки в Python3

Я пытаюсь написать массив (список?) В текстовый файл с помощью Python 3. В настоящее время у меня есть:

def save_to_file(*text):

    with open('/path/to/filename.txt', mode='wt', encoding='utf-8') as myfile:
        for lines in text:
            print(lines, file = myfile)
    myfile.close

Это записывает то, что выглядит как массив прямо в текстовый файл, т.е.

['element1', 'element2', 'element3']
[email protected]:/path$

То, что я хочу сделать, - создать файл с

element1
element2
element3
[email protected]:/path$

Я пробовал разные способы прокрутки и добавления "\n", но кажется, что запись сбрасывает массив за одну операцию. Вопрос аналогичен Как написать список строк в файл, добавив новые строки? но синтаксис выглядел так, как будто для Python 2? Когда я попробовал модифицированную версию:

def save_to_file(*text):

    myfile = open('/path/to/filename.txt', mode='wt', encoding='utf-8')
    for lines in text:
        myfile.write(lines)
    myfile.close

... оболочка Python дает "TypeError: должен быть str, а не список", который, я думаю, обусловлен изменениями между Python2 и Python 3. Что мне не хватает, чтобы получить каждый элемент в новой строке?

EDIT: Спасибо @agf и @arafangion; Объединив то, что вы написали, я придумал:

def save_to_file(text):

    with open('/path/to/filename.txt', mode='wt', encoding='utf-8') as myfile:
        myfile.write('\n'.join(text))
        myfile.write('\n')

Похоже, что у меня была часть проблемы с "* текстом" (я прочитал, что расширяет аргументы, но не нажимал, пока вы не написали, что [element] становится [[element]], что я получаю str-not- тип списка, я все время думал, что мне нужно сказать определение, что он получает список/массив, переданный ему, и что просто указание "тест" будет строкой.) Он работал, как только я изменил его только на текст и использовал myfile. write with join, а дополнительный \n помещает в окончательную новую строку в конце файла.

Ответ 1

myfile.close - избавиться от этого, где вы используете with. with автоматически закрывается myfile, и вы должны назвать close, как close() в любом случае для него, чтобы сделать что - нибудь, когда вы не используете with. Вы должны всегда использовать with Python 3.

with open('/path/to/filename.txt', mode='wt', encoding='utf-8') as myfile:
    myfile.write('\n'.join(lines))

Не используйте print для записи в файлы - используйте file.write. В этом случае вы хотите написать несколько строк с разрывами строк между ними, поэтому вы можете просто присоединить строки с помощью '\n'.join(lines) и написать строку, которая создается непосредственно в файле.

Если элементы lines не являются строками, попробуйте:

    myfile.write('\n'.join(str(line) for line in lines))

сначала конвертировать их.

Вторая версия не работает по другой причине. Если вы пройдете

['element1', 'element2', 'element3']

в

def save_to_file(*text):

это станет

[['element1', 'element2', 'element3']]

потому что * помещает каждый аргумент в список, даже если то, что вы проходите, уже является списком.

Если вы хотите поддерживать передачу нескольких списков и записывать их один за другим,

def save_to_file(*text):

    with open('/path/to/filename.txt', mode='wt', encoding='utf-8') as myfile:
        for lines in text:
            myfile.write('\n'.join(str(line) for line in lines))
            myfile.write('\n')

или, только для одного списка, избавиться от * и делать то, что я сделал выше.

Изменить: @Arafangion прав, вы должны, вероятно, просто использовать b вместо t для записи в ваши файлы. Таким образом, вам не нужно беспокоиться о том, как разные платформы обрабатывают новые строки.

Ответ 2

Там много ошибок.

  1. Ваш отпечаток испорчен.
  2. Атрибут 'text' в файле save_to_file относится ко всем аргументам, а не только к определенному аргументу.
  3. Вы используете "текстовый режим", что также сбивает с толку. Вместо этого используйте двоичный режим, чтобы у вас было согласованное и определенное значение для "\n".

Когда вы повторяете "строки в тексте", из-за этих ошибок то, что вы на самом деле делаете, это итерирование ваших аргументов в функции, потому что "текст" представляет все ваши аргументы. Это то, что делает "*". (По крайней мере, в этой ситуации. Строго говоря, он повторяет все остальные аргументы - прочитайте документацию).