在Python程序中读取管道输入文件的内容

时间:2019-07-05 00:08:57

标签: python-3.x stdin

我必须阅读已传递到Python程序中的文本文件的内容。可以按以下方式将文件传递到输入文件

  1. 您的程序必须接受来自两个来源的输入:在命令行参数中传递的文件名和STDIN。例如,在Linux或OSX上,./myprogram input.txt./myprogram < input.txt都应该工作。

我不知道该怎么做。

if __name__ == '__main__': 
  # I don't know what to do here.

输入文件包含以下几行,并且每一行都需要解析。

Add Tom 4111111111111111 $1000
Add Lisa 5454545454545454 $3000
Add Quincy 1234567890123456 $2000
Charge Tom $500
Charge Tom $800
Charge Lisa $7
Credit Lisa $100
Credit Quincy $200

每当我尝试python myprogram.py > input.txt时,程序就会挂起。如果有帮助,我正在使用Python 3.6.5。

更新:

我尝试了以下方法:

(env) myproject (master) $ python main.py > test.txt
testing testing testing
1 2 3
1 2 3

该文件将创建一个新文件(如果不存在),或使用输入的内容覆盖现有文件。在这种情况下,将使用上述内容创建一个名为test.txt的新文件。

更新#2

我尝试过这样的事情

if __name__ == '__main__':
  for line in sys.stdin.readline():
      print (line)

对于这样的一行

Add Tom 4111111111111111 $1000

每个字符都以新行显示,如

A
d
d

T
o
m

. . .

我希望所有字符都打印在一行上。

2 个答案:

答案 0 :(得分:0)

sys.argv是一个列表,其中包含调用程序所使用的参数(如果有)。

如果它是一个元素长,那么将在调用程序时不带任何参数(脚本名称本身是第一个参数,因此它实际上没有计数),因此您应该从sys.stdin中读取。 / p>

否则,如果它具有两个或多个元素,则以文件名作为参数调用程序,因此您应该打开该文件并将其用作输入。

答案 1 :(得分:0)

这对我来说效果最好。 https://docs.python.org/3/library/fileinput.html

  

这会遍历sys.argv [1:]中列出的所有文件的行,如果列表为空,则默认为sys.stdin

经过反复试验,这是我想出的

def handle_command_line_inputs():
    """Read the contents of the file piped through the command line.

    Once the operations are executed, then the balance is ready to be displayed
    """
    logging.info('Reading from the file')
    for line in fileinput.input():
        print(line)
        # My custom logic

这会打印每一行。

在我的单元测试中

from unittest import mock


def get_test_file():
    current_path = os.path.dirname(os.path.realpath(__file__))
    return os.path.normpath(os.path.join(current_path, 'input.txt'))


def read_input_file():
    """Simulates the generators that read file contents."""
    input_file = get_test_file()
    with open(input_file, 'r') as f:
        for line in f:
            yield line


@mock.patch('fileinput.input', side_effect=read_input_file)
def test_handle_command_line_inputs(mocked_fileinput):

    myprogram.handle_command_line_inputs()
    # Run your assertions.