0

我有一个从命令提示符获取输入文件名的 python 脚本。我创建了一个列表来存储所有输入文件并将其传递给一个函数以创建一个新文件,所有输入文件一次合并。现在,我将这个新编写的文件作为输入传递给另一个函数。我收到一条错误消息

TypeError:强制转换为 Unicode:需要字符串或缓冲区,找到列表

代码:

file_list = []                                                                                                                                                                                                                                                                                                                        
for arg in range(1,len(sys.argv)-2):    
    file_list.append(sys.argv[arg])
    process_name = sys.argv[len(sys.argv)-1]
integrate_files(file_list,process_name)

def integrate_files(file_list,process_name):
    with open('result.log', 'w' ) as result:        
       for file_ in file_list:
          for line in open( file_, 'r' ):
             result.write( line )
    start_process(result,process_name)

def start_process(result,process_name):
    with open(result,'r') as mainFile:
       content = mainFile.readlines()

我在带有单词with.open()的行中突出显示了此错误。我试图打印 result.log 文件的绝对路径。它在 0x000000000227578 处打印关闭的文件“result.log”,模式“w”。我哪里错了?我应该如何创建一个新文件并将其传递给函数?

4

4 回答 4

1

您的问题是这result是一个关闭的文件对象:

start_process(result,process_name)

我想你想要

start_process('result.log', process_name)

你可以清理一下脚本

import shutil
                                                                                            file_list = sys.argv[1:-1]
process_name = sys.argv[-1]
integrate_files(file_list,process_name)

def integrate_files(file_list,process_name):
    with open('result.log', 'w' ) as result:        
       for file_ in file_list:
           with open(file_) as infile:
               shutil.copyfileobj(infile, result)
    start_process('result.log',process_name)

def start_process(result,process_name):
    with open(result,'r') as mainFile:
       content = mainFile.readlines()
于 2014-12-23T15:35:57.430 回答
1

问题在这里:

with open('result.log', 'w' ) as result:        
   # ...
start_process(result,process_name)

由于您在 中重新打开文件start_process,因此您应该只传递名称:

start_process(result.name, process_name)

或者只是明确的:

start_process('result.log', process_name)
于 2014-12-23T15:36:33.890 回答
1

当您编写时with open('result.log', 'w') as result:,您将result成为表示磁盘上实际文件的对象。这与文件不同。

您当然可以将其传递result给另一个函数。但是由于它将是实际的文件对象,而不是文件名,因此您不能将其传递给open-open需要一个文件名,并查找具有该名称的文件,以便创建一个新的文件对象。

您可以在该文件对象上调用方法,但它们都不会真正重新打开文件。相反,最简单的事情是记住并传递文件名,这样就start_process可以open了。

如@matsjoyce 的答案所示,文件对象记住了原始文件名。所以你可以传递对象,并start_process获得名称。但这很乱。真的,只是传递名称。(您可以像 mats 所示的那样,result.name显式传递而不是先创建自己的name变量)。传递文件对象通常不是你想要的——只有当你想跨函数拆分读/写工作时才这样做(并且有充分的理由)。

于 2014-12-23T15:38:30.463 回答
0

在这:

with open('result.log', 'w' ) as result:

当你result在上面定义时,你只是为那个单一的循环定义它,所以当你调用它时它不会通过start_process

因此,要么更改start_process为:

with open('result.log','r') as mainFile:

或者您可以将字符串传递给result.logstart_process 不是变量result

file_list = []                                                                                                                                                                                                                                                                                                                        
for arg in range(1,len(sys.argv)-2):    
    file_list.append(sys.argv[arg])
    process_name = sys.argv[len(sys.argv)-1]
integrate_files(file_list,process_name)

def integrate_files(file_list,process_name):
    with open('result.log', 'w' ) as result:        
       for file_ in file_list:
          for line in open( file_, 'r' ):
             result.write( line )
    start_process('result.log',process_name)

def start_process(result,process_name):
    with open(result,'r') as mainFile:
       content = mainFile.readlines()
于 2014-12-23T15:45:37.227 回答