简体   繁体   English

通过将文件作为参数传递给python脚本中的函数来写入和读取新文件

[英]Writing and reading a new file by passing the files as an argument to a function in a python script

I have a python script that gets input file names from the command prompt. 我有一个从命令提示符获取输入文件名的python脚本。 I created a list to store all the input files and pass that to a function to create a new file with all the input files merged at once. 我创建了一个列表来存储所有输入文件,并将其传递给函数以创建一个新文件,其中所有输入文件都将立即合并。 Now, I pass this newly written file as an input to another function. 现在,我将此新编写的文件作为输入传递给另一个函数。 I am getting an error message 我收到一条错误消息

TypeError: coercing to Unicode: need string or buffer, list found TypeError:强制转换为Unicode:需要字符串或缓冲区,找到列表

Code: 码:

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()

I am getting this error highlighted at the lines having the word with.open() . 我在带有单词with.open()的行上突出显示了此错误。 I tried to print the abspath of the result.log file. 我试图打印result.log文件的绝对路径。 It printed closed file 'result.log', mode 'w' at 0x000000000227578 . 在0x000000000227578上打印了关闭文件'result.log',模式为'w' Where am I going wrong ? 我要去哪里错了? How should I create a new file and pass it to a function? 我应该如何创建一个新文件并将其传递给函数?

Your problem is that result is a closed file object: 您的问题是result是一个关闭的文件对象:

start_process(result,process_name)

I think you want 我想你要

start_process('result.log', process_name)

You could clean the script up a bit with 您可以使用以下方法清理脚本

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()

The issue is here: 问题在这里:

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

Since you reopen your file in start_process , you should just pass the name: 由于您是在start_process重新打开文件的,因此您只需传递名称:

start_process(result.name, process_name)

Or just be explicit: 或者只是明确:

start_process('result.log', process_name)

When you write with open('result.log', 'w') as result: , you make result be an object representing the actual file on disk . with open('result.log', 'w') as result:写入with open('result.log', 'w') as result: ,您使result代表磁盘上实际文件对象 That is different from the name of the file. 这与文件不同。

You certainly can pass that result to another function. 您当然可以将result传递给另一个函数。 But since it will be the actual file object, and not a file name, you can't pass that to open - open expects a name of a file, and looks for the file with that name, in order to create a new file object. 但是,因为这将是实际的文件对象,而不是一个文件名,你不能传递到open - open期望一个文件的名称,并查找与该名称的文件,以创建一个新的文件对象。

You can call methods on that file object, but none of them will actually re-open the file. 您可以在该文件对象上调用方法,但实际上没有一个方法可以重新打开文件。 Instead, the simplest thing is to remember and pass the file name , so that start_process can open it again. 相反,最简单的方法是记住并传递文件名 ,以便start_process可以再次open它。

As shown in @matsjoyce's answer, the file object remembers the original file name. 如@matsjoyce的答案所示,文件对象会记住原始文件名。 So you could pass the object, and have start_process get the name. 因此,您可以传递对象,并让start_process获得名称。 But that's messy. 但这很混乱。 Really, just pass the name. 真的,只要输入名称即可。 (You could, like mats showed, pass result.name explicitly instead of making your own name variable first). (您可以像显示的垫子一样,显式地传递result.name而不是先创建自己的name变量)。 Passing file objects around is usually not what you want - do it only when you want to split the reading/writing work across functions (and have a good reason for that). 传递文件对象通常不是您想要的-仅当您希望将读取/写入工作分配给各个函数时才这样做(并且有充分的理由)。

In this: 在此:

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

When you define result above, you are only defining it for that single loop, so it won't pass when you call start_process 当您在上面定义result ,您只为单个循环定义了result ,因此在调用start_process时不会通过

So either change start_process to: 因此,可以将start_process更改为:

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

Or you could pass the string result.log into start_process instead of the variable result : 或者,您可以将字符串result.log传递给start_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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM