Django 中的cached_property 与Python 的functools 之间有什么区别?

lmi*_*asf 22 python django python-3.8 python-3.9

Django 有一个名为 的装饰器cached_property,可以从django.utils.functional. 另一方面,Python 3.8 添加了cached_property标准库,可以从functools.

两者是等价的,即它们可以互换吗?或者两者有什么区别?何时使用其中一种或另一种是否有最佳实践?

Abd*_*kat 18

经过一些研究后,两者基本上以相同的方式工作,您会看到的唯一区别在于错误处理和性能。Django 的问题跟踪器上有一个票证#30949functools.cached_property ,可以用来代替django.utils.functional.cached_property.

您可以查看django版本 [ GitHub] 的源代码 [ GitHub] 。基本区别是 functool 的版本做了更多的错误处理,主要区别是 functool(Python 3.12 之前的版本)使用锁定机制来保证线程安全,这导致与 Django 版本相比性能下降。从上面链接的票证中完成的一些基准测试来看,Django 的版本在性能方面似乎更加高效:functools.cached_property

% python benchmark.py
.....................
Django Cache: Mean +- std dev: 12.8 ms +- 0.2 ms
.....................
Python Cache: Mean +- std dev: 113 ms +- 2 ms
Run Code Online (Sandbox Code Playgroud)

Python 的 bug 跟踪器上也有一个与此相关的问题 43468 。请注意,这种锁定行为在 Python 3.12 版本中已被删除,现在性能应该基本相似。

总之,如果您使用Python 3.12+,则更喜欢 functools 版本,否则如果线程安全不是问题,请使用 Django 版本,否则您可能需要使用 functools 版本。