1

我有一个脚本,应该读取位于同一目录中的用户指定的 2 列 csv 文件,对数据进行一些数学运算,然后将结果打印到另一个用户定义的 csv 文件 stdout。我在 2.7.5 中做到了,但现在终于移到了 3.2,它不起作用。我知道这并不令人震惊,但我在编程方面非常缺乏经验,而且我无法弄清楚如何让它在 Python 3 中工作。

我已经将代码剥离为过去可以工作的基本阅读和打印元素,尽管做了一些更明显的修改,但它仍然无法在 3.2 中工作,它只是卡住了,永远不会打印到新文件。我曾尝试使用 2to3.py 但它会引发错误的输入解析错误并且没有进行任何更改!我宁愿确切地了解为什么它现在无论如何都不起作用。

我想要的命令类型是;

somedirectory>myscript inputdata.csv > outputdata.csv

这是 Python 2.7.5 脚本的精简版,它可以工作,所以你可以看到我在做什么,(我已经离开了所有的导入)

import fileinput, math, sys, numpy as np
from numpy import linspace, loadtxt, ones, convolve
from optparse import OptionParser

def main():
    parser = OptionParser() 
    options,args = parser.parse_args()
    try:
        data = [(line.rstrip()).split(',') for line in fileinput.input(args)]
    except IOError as detail:
        print >> sys.stderr, detail
        sys.exit(2)

    '''kept these lines in just to make sure the data is in the same format as when it worked before'''
    t = [float(row[0]) for row in data]
    m = [float(row[1]) for row in data]
    result = [[a,b] for a,b in zip(t, m)]

    for line in result:
        print >> sys.stdout, str(line[0]) + ',' + str(line[1])

options = 0
if __name__ == "__main__":
    main()

显然 Print 现在是一个函数,不推荐使用的 Optparse 可以转换为 Argparse 等

所以我认为这样的事情会很好,

import fileinput, math, sys, inspect, numpy as np
from numpy import linspace, loadtxt, ones, convolve
from argparse import ArgumentParser

def main():
    parser = ArgumentParser()   
    options,args = parser.parse_args()
    try:
        data = [(line.rstrip()).split(',') for line in fileinput.input(args)]
    except IOError as detail:
        print(detail, file=sys.stderr)
        sys.exit(2)

    '''kept these lines in just to make sure the data is in the same format as when it worked before'''
    t = [float(row[0]) for row in data]
    m = [float(row[1]) for row in data]
    result = [[a,b] for a,b in zip(t, m)]

    for line in result:
        print(str(line[0]) + ',' + str(line[1]), file=sys.stdout)

options = 0
if __name__ == "__main__":
    main()

这可能存在一些明显的问题,但是在研究了所有元素之后,我被困在它到底在哪里崩溃了。

此外,可能有更好的方法来读取和写入这种类型的 csv 文件,我只是坚持这样做,因为我知道它确实有效。例如,我知道 csv 模块,但是我找不到任何从命令行在用户指定的文件上使用它的示例,例如我需要它的方式,我可以找到的所有示例都定义了要在脚本本身中打开的文件。

先感谢您。

4

2 回答 2

0

代码之前的一些事情。如果您使用该argparse模块,则必须指定它必须接收文件名作为输入。这就是我对add_argument. 由于参数不是可选的,如果用户没有指定文件名,应用程序将退出。

如果用户指定了文件名,我会尝试打开它并创建一个 csv 阅读器。csv阅读器只是一个解析文件的迭代器,所以我可以遍历每一行,我这样做并填充结果列表。填充列表后,应用程序将遍历列表并打印出所有元素。try/except是否有任何问题。

import io
import csv
import argparse

def main():
    # Create the parser
    parser = argparse.ArgumentParser()
    parser.add_argument('filename', help='Name of the file you want to load')
    args = parser.parse_args()

    result = []
    with io.open(args.filename, 'r', encoding='utf-8') as f:
        reader = csv.reader(f)
        for row in reader:
            result.append([row[0], row[1]])

    for item in result:
        print('{0}, {1}'.format(*item))

if __name__ == "__main__":
    try:
        main()
    except Exception as e:
        print('Something went wrong {0}'.format(e))
于 2013-08-17T22:07:14.877 回答
0

main有效,只需更改print

def main():
    parser = OptionParser()
    options,args = parser.parse_args()
    try:
        data = [(line.rstrip()).split(',') for line in fileinput.input(args)]
    except IOError as detail:
        print(detail, file=sys.stderr)
        sys.exit(2)

    '''kept these lines in just to make sure the data is in the same format as when it worked before'''
    t = [float(row[0]) for row in data]
    m = [float(row[1]) for row in data]
    result = [[a,b] for a,b in zip(t, m)]

    for line in result:
        print(', '.join(str(x) for x in line), file=sys.stdout)

你没有从第二个版本中得到任何东西的原因是缩进sys.exit(2)

except IOError as detail:
    print(detail, file=sys.stderr)
sys.exit(2)

它退出而不进入正常输出

对 argparse 进行更正(允许 1 个或多个输入文件):

def main():
    parser = ArgumentParser()
    parser.add_argument('infiles',nargs='+')
    args = parser.parse_args()
    try:
        data = [(line.rstrip()).split(',') for line in fileinput.input(args.infiles)]
    except IOError as detail:
        print(detail, file=sys.stderr)
        sys.exit(2)

    '''kept these lines in just to make sure the data is in the same format as when it worked before'''
    t = [float(row[0]) for row in data]
    m = [float(row[1]) for row in data]
    result = [[a,b] for a,b in zip(t, m)]

    for line in result:
        print(', '.join(str(x) for x in line))

或者您可以让您argparse打开文件(并在需要时引发错误):

import argparse
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('infiles',nargs='+', type=argparse.FileType('r'))
    args = parser.parse_args()
    data = [row for file in args.infile for row in csv.reader(file)]

    '''kept these lines in just to make sure the data is in the same format as when it worked before'''
    t = [float(row[0]) for row in data]
    m = [float(row[1]) for row in data]
    result = [[a,b] for a,b in zip(t, m)]

    for line in result:
        print(', '.join(str(x) for x in line))

FileType也识别'-'stdin(或对于('w')文件,stdout

于 2013-08-18T01:08:01.773 回答