3

在django python的开源代码中,我多次看到这样的场景

if request.META and 'HTTP_REFERER' in request.META:

同样,我也看到了这两个 if 条件

if request.POST and 'next' in request.POST:
if request.GET and 'next' in request.GET:

我相信在这些情况下,只有一个条件就足以检查 if 条件,例如

if 'HTTP_REFERER' in request.META:
if 'next' in request.POST:
if 'next' in request.GET:

那么为什么大多数时候人们使用前面的一次,就像双重检查一样,或者在某些情况下,第一个双重检查条件可能有用而后面的单一检查条件可能会失败?

4

3 回答 3

6

它只能通过检查来实现
request.META.get('HTTP_REFERER') ,而
request.REQUEST.get('next')
不是检查request.POSTrequest.GET

于 2012-07-23T07:40:47.983 回答
2

在一种(假设的)情况下,您的解决方案会失败:

>>> request.POST = None
>>> 'next' in request.POST
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: argument of type 'NoneType' is not iterable

但是,如果您可以确定request.POST永远不会None,那么您的解决方案就可以了。

在空字典的情况下它会慢一点,因为if 'foo' in request.POST如果(快速)空性测试已经失败,则可以跳过检查。另一方面,如果字典不为空,它会更快。

>>> import timeit
>>> timeit.timeit(setup="a = {}", stmt="if a and 'next' in a: pass")
0.028279806566242852
>>> timeit.timeit(setup="a = {}", stmt="if 'next' in a: pass")
0.04539217556517272
>>> timeit.timeit(setup="a = {'foo':'bar'}", stmt="if a and 'next' in a: pass")
0.07471092295071458
>>> timeit.timeit(setup="a = {'foo':'bar'}", stmt="if 'next' in a: pass")
0.045236056421884996
>>> timeit.timeit(setup="a = {'next':'bar'}", stmt="if a and 'next' in a: pass")
0.0851067469988891
>>> timeit.timeit(setup="a = {'next':'bar'}", stmt="if 'next' in a: pass")
0.0520663758715898

所以我想这是一个微优化的问题。在这种情况下,我调用 Python 之禅:显式优于隐式。

于 2012-07-23T07:37:41.987 回答
2

我刚刚 grepped 了 django 的整个(当前 git)源,并没有找到你提到的所有三个条件的一次出现。

只要您可以假设所有三个字典都已设置,那么您完全正确地满足一个条件。看看 django 代码,我相信你可以假设。

编辑django 文档也建议将始终设置这些字典。

于 2012-07-23T07:41:56.207 回答