【问题标题】:Django BinaryField retrieved as memory position?Django BinaryField 检索为内存位置?
【发布时间】:2016-03-19 04:34:42
【问题描述】:

我用以下代码编写了一个简短的单元测试:

my_object = MyObject()
my_object.data = b'12345'

my_object.save()
saved_object = MyObject.objects.first()

assert saved_object.data == my_object.data

其中MyObject 定义为:

class MyObject(models.Model):
    data = models.BinaryField(default=None)

我希望断言能够通过,因为我只是保存一些字节数据然后检索它。但是,我最终得到:

AssertionError: assert <memory at 0x10e2abc48> == b'12345'

我猜它与直接将字节字符串保存到二进制字段有关。另一方面,保存成功似乎很奇怪。而且我很难找到 Django 的BinaryField 的一些好的示例用法。谁能向我解释这里发生了什么或我做错了什么?非常感谢。

【问题讨论】:

    标签: python django database python-3.x binary


    【解决方案1】:

    Django 将BinaryField 的内容标准化为一个缓冲区。在 Python2 中以 buffer 和在 Python3 中的 memoryview 为具体。

    你可以在源代码中看到:

    在 Python2 中,buffer 没有实现比较逻辑,这就是您的断言失败的原因:

    Python 2.7.11
    >>> m = buffer(b'hello')
    >>> m == b'hello'
    False
    >>> bytes(m) == b'hello'
    True
    

    但它确实实现了其他操作,例如切片和长度:

    >>> len(m)
    5
    >>> m[1:]
    'ello'
    

    在 Python 3 中,情况要好得多,因为它实现了所有预期的操作:

    Python 3.5.1
    >>> m = memoryview(b'hello')
    >>> m
    <memory at 0x109e8b108>
    >>> bytes(m)
    b'hello'
    >>> m == b'hello'
    True
    >>> bytes(m) == b'hello'
    True
    >>> len(m)
    5
    >>> m[1:]
    <memory at 0x109e8b1c8>
    

    我不确定 Django 这样做的原因,但我的猜测是为了提高效率。缓冲区在处理内存方面效率更高。例如,当您切片时,它可以重用相同的内存而不是分配更多的内存。

    【讨论】:

    • 这无疑解释了问题以及解决问题的方法。但是,还有另一件事。如果我将代码更改为使用assert bytes(saved_object.data) == my_object.data,则测试通过。我正在使用 Python 3,您的示例按照您的说明运行。但是,当通过 Django 保存和检索测试时,与 memoryview 直接比较字节数据仍然失败。这不是很重要,但是您是否知道为什么在这种情况下内存视图 必须 转换回字节才能进行比较,但对于没有 Django 的情况则不然?
    • 哪个 Python3 版本?
    • 3.5.0 (与我用于运行上述示例的相同,如您所述)。 Django 1.8 版。
    • 嗯。不知道。从错误消息看来,您使用的是 pytest。也许这会有所作为?
    • 我也觉得可能是这样,所以我将您的示例代码转换为测试表单并尝试使用 pytest 运行它。在那种情况下测试通过了,所以它似乎是别的东西。无论如何,仅将 memoryview 强制转换为字节就足以满足我的情况。因此,感谢您对此和背后的理解。
    猜你喜欢
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    • 2016-02-26
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2020-09-29
    相关资源
    最近更新 更多