3

django pythonのオープンソースコードで何度も、私はこのようなシナリオを見てきました

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

同様に私はこれらの2つの条件も見ました

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

このような場合のif条件を確認するには、1つの条件だけで十分だと思います。

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

では、なぜほとんどの場合、以前の1回を使用するのでしょうか。それは、ダブルチェックのようなものですか、それとも最初のダブルチェック条件が役立つ一方で、後のシングルチェック条件が失敗するシナリオがあるのでしょうか。

4

3 に答える 3

6

それは、それをチェックする代わりに、
request.META.get('HTTP_REFERER') またはをチェックすることによってのみ達成することができます
request.REQUEST.get('next')
request.POSTrequest.GET

于 2012-07-23T07:40:47.983 に答える
2

ソリューションが失敗する(架空の)ケースが1つあります。

>>> 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のZenを呼び出します。明示的は暗黙的よりも優れています。

于 2012-07-23T07:37:41.987 に答える
2

djangoの(現在のgit)ソース全体を調べたところ、あなたが言及した3つの条件文すべての出現は1つも見つかりませんでした。

そして、3つの辞書がすべて設定されていると想定できる限り、1つの条件で十分です。そして、djangoコードを見ると、それを想定できると思います。

編集:また、djangoのドキュメントは、これらの辞書が常に設定されることを示唆しています。

于 2012-07-23T07:41:56.207 に答える