【问题标题】:Print works, write doesn't. How come?打印有效,写入无效。怎么会?
【发布时间】:2013-11-10 20:50:19
【问题描述】:

我已经测试了下面的代码,除了第 29 行之外,一切都按照我的预期进行。final.write(invrow) 实际上并没有写入文件。当我使用简单的打印 invrow 时,它显示没有问题。我没有错误,这里发生了什么?我错过了什么?我做错了什么?

import csv


inv = csv.DictReader(open('ireport.txt', 'rU'), dialect='excel-tab', delimiter="\t")
vbr = csv.DictReader(open('vb.txt', 'rU'), dialect='excel-tab', delimiter="\t")
mainr = csv.DictReader(open('main.txt', 'rU'), dialect='excel-tab', delimiter="\t")

final = open('ireport2.tab', 'w')

inva = []
maina = []
vba = []


for row in inv:
    inva.append(row)

for row in mainr:
    maina.append(row)

for row in vbr:
    vba.append(row)

for invrow in inva:
    for mainrow in maina:
        try:
            if invrow['\xef\xbb\xbfPART_CODE'] == mainrow['PART CODE']:
                invrow['MAINQTY'] = mainrow['ON-HAND']
                print invrow # works
                final.write(invrow) #doesn't work. Why?
        except TypeError:
            pass
        except ValueError:
            pass

final.close()

【问题讨论】:

  • 我不能肯定,但是如果您以wb 而不是w 打开文件呢?你能描述一下“不起作用”是什么意思吗?
  • 你能提供回溯吗?
  • except TypeError: pass 真的很可疑!默默地丢弃错误通常不是一个好主意。
  • 取出TypeErrorValueError 异常处理程序:它们很可能隐藏了您应该看到的错误。
  • 您也明确地关闭了文件final.close(),但如果程序干净退出,这应该不是问题。在这些情况下,通常使用with 语句。 with open(outfile, "w") as final:

标签: python file python-2.7 csv


【解决方案1】:

print 在每个参数上自动调用strwrite 没有。

所以,如果你传递一个字符串,它们都可以工作,而且实际上做的事情完全相同。但如果你传递了不同的东西,write 将引发 TypeError: expected a character buffer object

在您的情况下,invrow 是一个字典,由csv.DictReader 返回。这不是一个字符串,所以你会得到TypeError

您没有收到错误的原因是您在代码中明确捕获并丢弃了 TypeErrors,使用该 except TypeError: pass 代码。


同时,我认为您想要在这里做的是使用csv.DictWriter 来写每一行:

writer = csv.DictWriter(final, inv[0].keys())

然后:

writer.writerow(invrow)

附带说明一下,您可以大大简化这一点。例如,DictReader 是可迭代的;如果您想列出它,只需调用list就可以了,不要循环遍历它和append一一。像这样:

inva = list(inv)
maina = list(main)
vba = list(vb)

但实际上,您只需将“内部”的maina 更改为list;最外面的inva,您可以直接在DictReader 上循环。而vba,你根本不用。

另外,如果您使用with 语句,则不需要显式的close。这有一个附带的好处,如果你的程序在中间退出并出现异常,文件将被刷新并关闭,所以你可以看到在错误之前写了什么。

最后,如果您要使用 try/except 来处理异常并继续绕过它们,您真的希望它打印或记录一些东西,以便您知道它发生了。事实上,我建议在初始开发过程中将try 排除在外,直到您知道它适用于未损坏的文件,并且仅在您开始处理损坏的文件时添加它。

把它们放在一起:

with open('main.txt', 'rU') as mainf:
    main = list(csv.DictReader(mainf, dialect='excel-tab', delimiter="\t")
with open('ireport.txt', 'rU') as invf, open('ireport2.tab', 'w') as finalf:
    inv = csv.DictReader(invf, dialect='excel-tab', delimiter="\t")
    final = csv.DictWriter(finalf, dialect='excel-tab', delimiter="\t",
                           fieldnames=inv.fieldnames)
    for invrow in inv:
        for mainrow in main:
            if invrow['\xef\xbb\xbfPART_CODE'] == mainrow['PART CODE']:
                invrow['MAINQTY'] = mainrow['ON-HAND']
                final.writerow(invrow)

【讨论】:

  • 我会试一试的。正如您可能猜到的那样,我对编程仍然很陌生,非常感谢每个人的见解。
【解决方案2】:

我真的不认为是这样,但由于其他人给出了很好的答案,你可能还需要这个作为最后的绝望修复。

几周前我设法得到了一个类似的错误,也使用 txt 文件。据我所知,您无法将某些 unicode/ascii/others 符号保存到 txt 文件中,例如 ♥☻☺♦♣♠ 在特定情况下,我将向您展示 2 个示例:

1:这会使它崩溃:

printablelog = open("examplefile.txt", "a")
printablelog.write("An example ♥☻☺♣ とかちそのラヒイスハレラテ and more text")
printablelog.close()

2:这会将其保存为字节,并且由于它以这种方式对其进行编码,因此您不会收到错误:

printablelogfixed = open("example.txt", "ab")
printablelogfixed.write(bytes("An example ♥☻☺♣ とかちそのラヒイスハレラテ and more text", 'UTF-8')) 
printablelogfixed.close()

祝你好运。

【讨论】:

    【解决方案3】:

    您只需要在您尝试编写的对象上调用 toString() 或类似方法。某些语言会隐式将其转换为可写对象,但您需要更明确地使用 Python。

    【讨论】:

    • Python 中没有toString 方法。最接近的等价物是 __str__,但您几乎不应该直接调用它。
    • 如果处理一个字典,那么你可以打电话给''.join('{}{}'.format(key, val) for key, val in adict.items())
    • 嗯,你可以,但为什么呢?例如,给定字典{1: '2', 3: '4'},这将给你'3412',这在任何地方都不太可能有用。你可能想要的是str(adict),或repr(adict),或json.dumps(adict),或pickle.dumps(adict),或其他有用的东西。或者,在 OP 的实际情况中,adict is 实际上是他想要的,他只是不想将其传递给file.write,而是传递给csv.DictWriter.writerow...
    • str(adict) 听起来很像我在回答中提到的 toString() 的类似方法。听起来你只是变得迂腐了。
    • 好吧,我想它是“迂腐的”,就像 Python 在 adict.toString()adict.str() 上引发 AttributeError 时一样迂腐。但我不考虑告诉人们如何实际编写有效的代码,或者至少给他们足够的信息以便他们可以在文档中搜索它(比较 [this](site:docs.python.org str) 到 [this ](site:docs.python.org toString)),过于迂腐。如果你连 Python 的基础知识都不知道,为什么要尝试回答 Python 问题呢?
    猜你喜欢
    • 2012-07-07
    • 1970-01-01
    • 2012-09-01
    • 2018-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-23
    • 1970-01-01
    相关资源
    最近更新 更多