来自命令行参数的文件搜索中的Python字

时间:2013-12-31 17:36:26

标签: python file exception exception-handling

我有一个6-7行的文本文件(test.txt)。其中3-4个中有“异常”一词。在这3-4行中,其中2行中也有“abc”一词。我的任务是编写一个程序,通过其输出,我将能够分隔包含用户输入的任何单词的行(word1),但不包括那些同时具有(word1)和(word2-例如“abc”的行:这也将是来自用户的输入)并将其写入新文件(test_mod.txt)。我必须从命令行参数执行此操作。所以这是命令提示符下的命令: “fileinput4.py test.txt test_mod.txt abc exception” 这里将排除包含“abc”和“exception”的行,并且将包含仅包含单词“exception”的行并将其复制到test_mod.txt中。 到目前为止,我有异常处理以下事项: 1.如果两个单词相同,则显示错误消息。 2.如果少于5个参数,则显示错误消息。 3.如果第一个文件名拼写错误,请显示错误消息 4.如果输入文件名和输出文件名相同,则显示错误消息。 如果有人输入文本文件中根本没有的单词,我也想要异常处理。但是我的代码中存在一些错误,而这件事情并没有发生。请帮助。无论何时我输入文件中没有的任何单词,都不会打印任何内容,并且创建新文件时没有任何我想要阻止的错误消息。 这是我的代码:

import sys
import os


def main(): #main method
 try:    
  f1 = open(sys.argv[1], 'r')         #takes the first input file in command line

  user_input1 = (sys.argv[3])    #takes the word which is to be excluded.
  user_input2 = (sys.argv[4])    #takes the word which is to be included.
  if sys.argv[1] == sys.argv[2]: 

       sys.exit('\nERROR!!\nThe two file names cannot be the same.') 

  if sys.argv[3] != sys.argv[4]:  

    for line in f1:
         if user_input2 or user_input1 in line:

           f2 = open(sys.argv[2], 'a') 

           if user_input1 in line:
              if user_input2 in line:
                   pass

           elif user_input2 in line:
              f2.write(line)

        else:
          sys.exit('\nOne of the words or both of them does not exist.')      


  if sys.argv[3] == sys.argv[4]:  

         sys.exit('\nERROR!!\nThe word to be excluded and the word to be included     cannot be the same.') 



 except IOError:
       print('\nIO error or wrong file name.')  
 except IndexError:
       print('\nYou must enter 5 parameters.') 
 except SystemExit as e:                       
       sys.exit(e)


if __name__ == '__main__':
  main()

1 个答案:

答案 0 :(得分:0)

详细阐述我的评论:

代码if user_input2 or user_input1 in line并不代表您的想法。您认为这意味着“如果user_input1中的lineuser_input2中有line”。但是,这是不正确的。

让我们看一个简单的例子:

if True or False in [0, 1, 2, 3, 4]:
    this_will_always_be_executed()
else:
    so_this_will_never_be_run()

if True or False in [0, 1, 2, 3, 4]并不意味着“True中的[0, 1, 2, 3, 4]False中的[0, 1, 2, 3, 4]是否属于if。”这意味着, or alternatively if True in False if (True) or (False in [0, 1, 2, 3, 4]) [0,1,2,3,4]`“。

换句话说,代码意味着 - TrueFalse in [0, 1, 2, 3, 4]始终为true,因此在执行代码期间,解释器永远不会检查是否True。它只看到if,然后进入True语句的正文。

您的代码中也会发生同样的事情。但是,它不太明显。您需要知道的是,Python在某些上下文中将所有类型的值解释为FalseTrue,而不仅仅是布尔值Falsea == b,它们就是表达式例如c in dTrue评估为。

对于内置类型,例如列表,整数,浮点数和字符串,当需要布尔值时,每个值的计算结果为bool(您可以通过调用函数bool(1) == bool(2) == bool("asdlkjhwar") == bool([1, 2, 3]) == True显式执行此操作),“空”值除外。所以bool(0) == bool([]) == bool("") == Falseuser_input2。在您的代码中,user_input1几乎总是非空字符串(或者至少您没有使用空字符串测试程序,line不在if (user_input2 in line) or (user_input1 in line)中。彻底测试的重要性。

要解决此问题,您可以将该行替换为if any(thing in line for thing in (user_input1, user_input2))(为了便于阅读而添加了括号)。但更好(恕我直言)就是这样做 - user_input。这值得了解,因为如果你进行类似的测试但是变量数量较大(例如 f1 = open(sys.argv[1], 'r') #takes the first input file in command line user_input1 = (sys.argv[3]) #takes the word which is to be excluded. user_input2 = (sys.argv[4]) #takes the word which is to be included. if sys.argv[1] == sys.argv[2]: sys.exit('\nERROR!!\nThe two file names cannot be the same.') if sys.argv[3] != sys.argv[4]: lines = f1.readlines() if any(any(argument not in line for argument in (user_input2, user_input1)) for line in lines): sys.exit('\nOne of the words or both of them does not exist.') for line in lines: f2 = open(sys.argv[2], 'a') if not (user_input1 in line and user_input2 in line): f2.write(line) 3,4,5和6)会更快。

另外,如评论中所述,您应该查看argparse模块。这将使你想要的更容易实现。

编辑:

试试这个:

This is the first line of the file.
This line's short.
This is a line of much greater length than any other in the file.
This line has five words.
The next line is a lie.
The previous line was true.
This is the last line in the file.

虽然您应该重写代码,但不要为第一个文件中的每一行打开文件。

示例文件处理:

示例文件:

>>> with open(filename) as f:
        for line in f:
            print(line)
            print("^That was a line of the file!")


This is the first line of the file.
^That was a line of the file!
This line's short.
^That was a line of the file!
This is a line of much greater length than any other in the file.
^That was a line of the file!
This line has five words.
^That was a line of the file!
The next line is a lie.
^That was a line of the file!
The previous line was true.
^That was a line of the file!
This is the last line in the file.
^That was a line of the file!

示例代码:

{{1}}

Here是文件处理教程,here是argparse的教程。