Python TypeError:导入文本文件时需要字符串或其他字符缓冲区对象

Posted

技术标签:

【中文标题】Python TypeError:导入文本文件时需要字符串或其他字符缓冲区对象【英文标题】:Python TypeError: expected a string or other character buffer object when importing text file 【发布时间】:2019-06-22 00:53:27 【问题描述】:

我对 python 很陌生。对于这个任务,我正在尝试导入一个文本文件,将 添加到 id,并从文本中删除标点符号。我试过这个方法How to strip punctuation from a text file。

import string
def readFile():

translate_table = dict((ord(char), None) for char in string.punctuation)
with open('out_file.txt', 'w') as out_file:
    with open('moviereview.txt') as file:
        for line in file:
            line = ' '.join(line.split(' '))
            line = line.translate(translate_table)
            out_file.write("<s>" + line.rstrip('\n') + "</s>" + '\n')

return out_file

但是,我收到一条错误消息:

TypeError: 应为字符串或其他字符缓冲区对象

我的想法是,在我拆分并加入行后,我得到了一个字符串列表,所以我不能使用 str.translate() 来处理它。但似乎其他人都有相同的东西并且它有效, 前任。 https://appliedmachinelearning.blog/2017/04/30/language-identification-from-texts-using-bi-gram-model-pythonnltk/ 在第 13 行的示例代码中。

所以我真的很困惑,有人可以帮忙吗?谢谢!

【问题讨论】:

使用" ".join(line.split(" ")) 毫无用处。你最终得到的正是你开始的东西。另外,错误发生在哪一行?我也认为这只是一个复制问题,但这是一些非常奇怪的缩进。 @Recessive 错误发生在“line = line.translate(translate_table)”这一行 这是 Python 2 还是 Python 3?如果是 Python 2,除非您使用 io.open 打开文件,而不是普通的内置 open,否则预计会失败。 【参考方案1】:

在这里回答是因为评论不允许我正确格式化代码:

def r():
    translate_table = dict((ord(char), None) for char in string.punctuation)
    a = []
    with open('out.txt', 'w') as of:
        with open('test.txt' ,'r') as f:
            for l in f:
                l = l.translate(translate_table)
                a.append(l)
                of.write(l)
    return a

此代码对我来说运行良好,没有错误。您可以尝试运行它,并以您运行的代码的屏幕截图作为响应吗?

【讨论】:

你用的是python3还是python2?我用python2试过了,还是不行。 python 3. 尝试将行 out_file.write("&lt;s&gt;" + line.rstrip('\n') + "&lt;/s&gt;" + '\n') 更改为 out_file.write(str("&lt;s&gt;" + line.rstrip('\n') + "&lt;/s&gt;" + '\n'))。另外,如果不起作用,请在每隔一行打印各种变量的打印语句。【参考方案2】:

在 Python 2 上,只有 unicode 类型具有采用 dicttranslate 方法。如果您打算使用任意文本,这里最简单的解决方案是在 Py2 上使用 Python 3 版本的open;它将无缝解码您的输入并生成 unicode 而不是 str

从 Python 2.6+ 开始,用 Python 3 版本替换普通的内置 open 很简单。只需添加:

from io import open

到文件顶部的导入。也可以删除line = ' '.join(line.split(' '));这绝对是一个无操作(它在单个空格上拆分为list,然后在单个空格上重新加入)。您可能还想添加:

from __future__ import unicode_literals

到the very top of your file(在您的代码所有之前);这将使您对纯引号的所有使用自动unicode 文字,而不是str 文字(在实际二进制数据前加上b 使其成为Py2 上的str 文字,Py3 上的bytes 文字)。

如果你可以使用上述解决方案是最好的,因为它会使你的代码在 Python 2 和 Python 3 上都能正常工作。如果你不能这样做,那么你需要改变你的translate调用以使用 Python 2's str.translate 期望的 API,这意味着完全删除 translate_table 的定义(不需要)并且只是这样做:

line = line.translate(None, string.punctuation)

对于 Python 2 的 str.translate,参数是从 0 到 255 的所有值的一对一映射表,作为第一个参数(None,如果不需要映射),第二个参数是一个字符串要删除的字符数(string.punctuation 已经提供)。

【讨论】:

首先感谢所有的解释!非常清楚。我尝试了您推荐的第一个解决方案,添加了从 io 和 future 导入。但现在我收到此错误:“UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 2561: ordinal not in range(128)” at line "for line in file:" 。是因为我输入的文本文件的内容吗? @YuheZhu:是的。您的输入文件可能不是您的语言环境的默认编码(locale.getpreferredencoding(False) 会告诉您默认的io.open 使用的是什么)。如果是这种情况,您需要明确指定 encoding 参数,例如with open('test.txt' ,'r', encoding='utf-8') as f: 如果文件是 UTF-8。 The codecs module has a list of standard encodings;我会尝试 UTF-8、UTF-16(如果在 Windows 上生成),然后是中文,gb18030 或其他一些统一的东亚或中文编解码器。 @YuheZhu:打开文件进行写入时,您可以匹配编码,但如果输入是特定于语言环境的编解码器,例如gb18030,您可能需要切换到可移植编码,例如@987654353 @ 处理所有 Unicode 字符,而不仅仅是 ASCII+东亚字符。 @YuheZhu:好的。不过要小心使用像'iso-8859-15' 这样的单字节ASCII 超集编码;它们是一对一的编码,涵盖所有或大多数可能的字节值。它们在 ASCII 上匹配,但它们中的每一个通常都可以有效地解码大多数随机字节字符串,因此除非有人检查结果是否有意义,否则最终不会引发异常,但结果仍然是乱码。不过,您绝对不想在输出文件中保留该编码;使用 UTF-8(自检),这样输出文件的未来用户就不会感到困惑了。 例如,iso-8859-15(又名latin-9)实际上与iso-8859-1(又名latin-1)相同,除了八个字节(共256个字节),所以如果这八个字节不'不显示,这两种编码是无法区分的。

以上是关于Python TypeError:导入文本文件时需要字符串或其他字符缓冲区对象的主要内容,如果未能解决你的问题,请参考以下文章

python3在pycharm中为什么导入random模块不能用? TypeError: 'module' object is not callable

python3在pycharm中为啥导入random模块不能用? TypeError: 'module' object is not callable

导入json文件报错,TypeError expected string or buffer

Python:当我导入 RandomForestClassifier 时出现“TypeError:无法使用块值操作”

python:TypeError:无法将str写入文本流

python 3.5: TypeError: a bytes-like object is required, not 'str'