2016-10-08 7 views
1

Most argumentsなぜforループ変数を作成するのが設計されたのか約ではなく、がループのローカルにあります。ループ外のfor-loop変数を安全に使用すること

明白なユースケースはこれです:

x = default_value 
for x in iterator: 
    # do stuff 
# do something with x here 

残念ながら、多くの場合、最初の行を忘れてしまった:イテレータが空の場合xが先に定義されていない場合

# should have set default value for x here 
# but forgot 
for x in iterator: 
    # do stuff 
# do something with x here 

だから、彼らはNameErrorを上げます。

この間違いは、ネストされたループを有する悪くなる:ここ

for y in outer_iterator: 
    # should have set default value for x here 
    # but forgot 
    for x in inner_iterator(y): 
     # do stuff 
    # do something with x 

inner_iterator(y)は、外側のループを介して、第2またはそれ以降の反復で空の場合代わりに、例外のサイレントエラーでx = default_value結果を忘れ。

inner_iterator(y)は外的な議論ではないので、これらの状況をテストするのは難しいので、空である場合に何らかの形で再現するテストがなければ、バグは検出されません。

すべてのユースケースは壊れやすいか、for-loop変数のスコープルールに頼っている安全な方法がありますか?

答えて

0

for-loop内で変数が設定されていることに頼るのは100%安全な方法ではありません。 100%保証を達成するには、for x in iterator or [None]:のようなことをすることができますが、これは同様の「それをすることを覚えてください」という問題を提起します。おそらく、デフォルトを設定するよりも「ピニング」になりますが、デフォルトではより明確になります。 for-loopスコープに頼っているのは、if (condition): x = somethingのようなもので、条件がfalseのときにxを呼び出すとどういうことが考えられますか?とにかくそのようなコードを書くのではなく、なぜfor-loopsにするのでしょうか?私は、それは、すべての変数をNoneにするか、関数の初めに他のデフォルトを設定するなど、すべての変数を宣言する習慣にしたいと思っています。

0

自分のスコープを持たないループの最も明白な理由は、外側のスコープの変数に値を割り当てるときに導入される複雑さです。

しかし、必ずしも反復された値を意味するわけではありません。以下を考慮してください:

total = 0 
for item in some_list: 
    total += item 

ループには独自の変数スコープがある場合、これを実装するのは悪夢です。 onsequencesの

一つはitemは、ループの外avaialableであるということですが、それは本当に良い方法があるという意味ではありません(または、あなたがを言うように「安全な」方法は)それを使用します。

使用できますが、注意する必要があります。

関連する問題