【问题标题】:TypeError: expected a character buffer object using .translateTypeError:预期使用 .translate 的字符缓冲区对象
【发布时间】:2019-02-27 10:23:09
【问题描述】:

我收到了错误:

TypeError: 需要一个字符缓冲区对象

在上面写着words=user_input_txt.translate(translate_table).lower().split() 的那一行。我检查了参数user_input_txt 的类型及其Unicode 类型。我不确定我做错了什么,也不太了解以前的帖子。如果有人能就如何解决问题提出建议,我将不胜感激!

def contains_bad_words(user_input_txt):
    """ remove punctuation from text 
        and make it case-insensitive"""
    translate_table = dict((ord(char), None) for char in string.punctuation)
    words = user_input_txt.translate(translate_table).lower().split()
    for bad_word in blacklist:
        for word in words:
            if word == bad_word:
                return True
    return False

编辑:我根据 Daniel 的建议修改了我的解决方案。但是,我现在收到错误消息:

TypeError: maketrans() 只需要 2 个参数(给定 1 个)。

有人可以告诉我我做错了什么吗?我读到string.maketrans 可以接受一个论点,只要它是一个字典。但是translate_table 不是字典吗?请帮忙!!

def contains_bad_words(user_input_txt):
    """ remove punctuation from text 
        and make it case-insensitive"""
    translate_table = dict((ord(char), None) for char in string.punctuation)
    translate_table_new = string.maketrans(translate_table)
    words = user_input_txt.translate(translate_table_new).lower().split()
    for bad_word in blacklist:
        for word in words:
            if word == bad_word:
                return True
    return False

第二次编辑: 所以我通过将 unicode 字符串转换为字符串并更改 maketrans 的参数数量来解决问题。但是,我仍然很困惑为什么我上面的解决方案不起作用。我在某处读到它可以接受 1 个参数,前提是它必须是一本字典,这显然是我所做的。有人可以帮助解释为什么上面的方法不起作用,但下面的方法起作用:

def contains_bad_words(user_input_txt):
    """ remove punctuation from text
        and make it case-insensitive"""
    user_typ = user_input_txt.encode()
    translate_table_new = maketrans(string.punctuation, 32*" ")
    words = user_typ.translate(translate_table_new).lower().split()
    for bad_word in blacklist:
        for word in words:
            if word == bad_word:
                return True
    return False

【问题讨论】:

  • 您的第二个示例是混合翻译类型。 Unicode 字符串使用翻译字典,而不是 string.maketransstring.maketranstranslate 的字节字符串版本准备一个 256 字节的翻译字符串。看我的回答。
  • 您输入的字符串类型是什么?这里真的很重要。 Python 2 允许您在字节字符串上调用 .encode,即使它已经是一个字节字符串,也使事情变得混乱,因此您的第三个示例可能不需要 .encode。试试print type(user_input_text) 并告诉我们结果。更好的是,制作一个具有示例输入、正确缩进并显示预期输出与实际输出的独立示例。请参阅minimal reproducible example 指南。
  • 嗨,马克!非常感谢您的帮助和详细的回复。我可以确认,当我打印 type(user_input_text) 时,类型是 Unicode。澄清一下,当我在上面的第一个代码上执行 python manage.py runserver 时,它运行良好。当我运行测试时,是否会出现此错误。我还没有开始对这个特定功能进行任何测试,所以我很困惑为什么会出现这个错误。由于我的输入是unicode,你同意上面第一个代码中的逻辑是正确的吗?
  • 是的,如果您的输入是unicode 字符串,那么您的第一个函数可以工作。如果您的输入是str,那么它会给出TypeError: expected a string or other character buffer object。所以你的测试必须通过str 而不是unicodeTypeError 异常的堆栈跟踪应该可以帮助您跟踪测试。
  • 非常感谢!这就说得通了。正在测试的字段是模型中的 charField,这就是所有测试用例都以字符串形式传递的原因。在您看来,您是否会建议我使用上面的第三个版本,因为我的测试通过 str 而不是 unicode?对不起新手问题,这是我第一次学习 Django 和 python

标签: python django python-2.7 unicode translate


【解决方案1】:

您的代码不是完整的示例。你的输入是什么很重要。

在 Python 2 中有两个版本的 translatestr.translateunicode.translate。以下是两者的帮助:

>>> help(str.translate)
Help on method_descriptor:

translate(...)
    S.translate(table [,deletechars]) -> string

    Return a copy of the string S, where all characters occurring
    in the optional argument deletechars are removed, and the
    remaining characters have been mapped through the given
    translation table, which must be a string of length 256 or None.
    If the table argument is None, no translation is applied and
    the operation simply removes the characters in deletechars.

>>> help(unicode.translate)
Help on method_descriptor:

translate(...)
    S.translate(table) -> unicode

    Return a copy of the string S, where all characters have been mapped
    through the given translation table, which must be a mapping of
    Unicode ordinals to Unicode ordinals, Unicode strings or None.
    Unmapped characters are left untouched. Characters mapped to None
    are deleted.

如果您有一个字节串 (str),那么表翻译要求必须是长度为 256 的字节串或无。 .translate 的可选第二个参数删除字符。

string.maketrans 可以生成 256 字节的字符串。它需要两个长度必须相同的参数。这是帮助:

>>> import string
>>> help(string.maketrans)
Help on built-in function maketrans in module strop:

maketrans(...)
    maketrans(frm, to) -> string

    Return a translation table (a string of 256 bytes long)
    suitable for use in string.translate.  The strings frm and to
    must be of the same length.

演示(a->1b->2c->3、删除def):

>>> import string
>>> test = 'abcdefg'  # byte string in Python 2
>>> test.translate(string.maketrans('abc','123'),'def')
'123g'

unicode 版本将 Unicode 序数字典转换为 Unicode 序数、Unicode 字符串或无。

演示(更改a->bc->xxx,并删除d):

>>> test = u'abcdefg' # Unicode string in Python 2
>>> xlat = {ord('a'):ord('b'),ord('c'):u'xxx',ord('d'):None}
>>> test.translate(xlat)
u'bbxxxefg'

因此,对于您的示例,您要删除标点符号。根据您使用的是字节字符串还是 Unicode 字符串,请选择以下选项之一:

>>> import string
>>> translate_table = dict((ord(char), None) for char in string.punctuation)
>>> u'abcd.,def'.translate(translate_table)
u'abcddef'

>>> import string
>>> 'abcd.,def'.translate(None,string.punctuation)
'abcddef'

【讨论】:

    【解决方案2】:

    .translate 不直接接受字典。您需要先通过str.maketrans 运行它。

    translate_table = dict((ord(char), None) for char in string.punctuation)
    translate_table = str.maketrans(translate_table)
    words = user_input_txt.translate(translate_table).lower().split()
    

    【讨论】:

    • 非常感谢您的回复!看起来 b/c 我正在使用 python 2.7,我不能使用 str.maketrans。所以我尝试了 string.maketrans(translate_table) 它告诉我 maketrans 只需要两个参数而不是一个。你能建议吗???
    猜你喜欢
    • 2013-04-18
    • 2012-09-17
    • 1970-01-01
    • 2016-01-24
    • 2020-04-02
    相关资源
    最近更新 更多