如何在嵌套循环中关闭 sys.stdout 以便它不会在文件中的内部循环之外复制打印语句

how to close sys.stdout in a nested loop so that it doesnt copy print statements outside inner loop in file

我是 python 3 的新手,我正在研究推文的情感分析。我的代码以一个 for 循环开始,该循环接收 50 条推文,我对这些推文进行了清理和预处理。在此之后(仍在for循环内)我想将每条推文保存在文本文件中(每条推文都在新行中) 代码如下:

    for loop:
        ..
        print statments
        ..
        if loop:
            filename=open("withnouns.txt","a")
            sys.stdout = filename
            print(new_words)#tokenised tweet that i want to save in txt file
            print("\n")
            sys.stdout.close()#i close it because i dont want to save print statements OUTSIDE if loop to be saved in txt file
        ..
        ..
        print statements

在 运行 之后显示错误:I/O 对第 71 行关闭文件的操作(if 循环后的第一个打印语句)

我的问题是,有什么方法可以暂时关闭然后打开 sys.stdout 并仅在 if 循环中激活它?

我不确定这是否正是您想要的,但您可以更改它

filename=open("withnouns.txt","a")
sys.stdout = filename
print(new_words)
print("\n")
sys.stdout.close()

filename=open("withnouns.txt","a")
filename.write(new_words + "\n")
filename.write("\n\n")
filename.close()

或者,你可以从sys.__stdout__得到sys.stdout的原始值,这样你的代码就变成了

filename=open("withnouns.txt","a")
sys.stdout = filename
print(new_words)
print("\n")
filename.close()
sys.stdout = sys.__stdout__

您根本不需要分配给 sys.stdout 。只需使用 file 参数告诉 print() 写入文件即可:

print(new_words, file=filename)
print("\n", file=filename)

现在不需要向 sys.stdout 分配任何内容,因为现在 print() 直接写入您的文件。

您还想将文件对象用作上下文管理器,因此它已关闭,或者您:

with open("withnouns.txt","a") as filename:
    print(new_words, file=filename)
    print("\n", file=filename)

无论如何您都不需要关闭 sys.stdout 引用,您想要关闭 filename 并将 sys.stdout 恢复到它以前的状态。

如果您确实需要替换 sys.stdout,您有几个选项,从最正确到最不正确:

  • 使用contextlib.redirect_stdout():

    import contextlib
    
    with contextlib.redirect_stdout(some_fileobject):
        # do things that write to stdout
    

    块的末尾stdout已为您解决。

  • 先手动存储sys.stdout

    old_stdout = sys.stdout
    sys.stdout = new_object
    try:
        # do things that write to stdout
    finally:
        sys.stdout = old_stdout
    
  • 使用sys.__stdout__ copy;这是在 start-up:

    上设置的
    sys.stdout = new_object
    try:
        # do things that write to stdout
    finally:
        sys.stdout = sys.__stdout__
    

    您需要考虑到 sys.stdout 可能在您的代码运行之前已被其他内容替换,将其恢复为 sys.__stdout__ 可能是错误的做法。

您混淆了两种不同的文件写入方式。

sys.stdout 将您的输出通过管道传输到 console/terminal。这可以写入文件,但非常迂回。

写入文件不同。在 python 中,如果您正在编写所有相同长度的值列表,您应该查看 csv module(也许即使您不是,它也很容易使用)。

在循环外打开文件。在循环中,逐行写入文件。在循环外关闭文件。如果您使用以下 "with" 语法,这将自动为您完成:

import csv
with open('file.csv') as f:
    writer = csv.writer(f, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)

    for loop:
        # tokenize tweet
        writer.writerow(tweet)

或者,循环遍历并将 tokenized-tweets 保存到 list-of-lists。然后,在循环之外和之后,将整个内容写入文件:

import csv
tweets = []
for loop:
    # tokenize tweet
    tweets.append(tweet)

with open('file.csv') as f:
    writer = csv.writer(f, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)
    writer.writerows(tweets)