简体   繁体   English

在循环外安全地使用for循环变量

[英]Safely using for-loop variables outside the loop

Most arguments about why the design decision was made to make for-loop variables not local to the loop suggest that there are popular use cases. 关于为什么要进行设计决策以使for循环变量不在循环本地的大多数争论都表明存在流行的用例。

The obvious use case is this: 明显的用例是这样的:

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

Unfortunately, often the first line is forgotten: 不幸的是,第一行经常被遗忘:

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

So when iterator is empty, they raise NameError if x was not defined earlier. 因此,当迭代器为空时,如果x之前未定义,则它们引发NameError

This mistake gets worse with nested loops: 嵌套循环会使此错误变得更糟:

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

Here forgetting the x = default_value results in a silent error instead of an exception if inner_iterator(y) is empty on the second or later iteration through the outer loop. 如果在外部循环的第二次或更多次迭代中inner_iterator(y)为空,则忘记x = default_value导致产生静默错误而不是异常。

Testing these situations is tough, because inner_iterator(y) is not an outside argument, so unless the test is lucky enough to somehow recreate the case when it's empty, the bug won't be detected. 测试这些情况非常困难,因为inner_iterator(y)并非外部参数,因此除非测试足够幸运,以某种方式可以在空的情况下重新创建该案例,否则不会检测到该错误。

Are all use cases fragile or is there a safe way to rely on the scoping rule of the for-loop variables? 所有用例都是脆弱的,还是有一种安全的方法来依赖for循环变量的作用域规则?

There is no 100% safe way to rely on a variable being set inside a for-loop unless you can be 100% sure that the iterator is never empty. 没有100%安全的方法依赖于在for循环内设置的变量,除非您可以100%确保迭代器永远不会为空。 To achieve the 100% assurance, you could do something like for x in iterator or [None]: , but this poses a similar "remembering to do it" problem. 为了获得100%的保证,您可以对it for x in iterator or [None]:做类似for x in iterator or [None]: ,但这会带来类似的“记住做到这一点”的问题。 It is probably more "pythonic" than setting defaults, but defaults may provide more clarity. 它可能比设置默认值更“ pythonic”,但是默认值可以提供更多的清晰度。 The whole relying on for-loop scoping is similar to something like if (condition): x = something and then contemplating about what if I call x when condition is false? 整个对for循环作用域的依赖类似于if (condition): x = something ,然后考虑如果条件为false时调用x会怎样? You probably would not write code like that anyway so why do it for for-loops? 无论如何,您可能都不会编写这样的代码,所以为什么要进行for循环? I like to make it a habit of declaring all variables that will be used outside upfront (eg, setting all variables to None or some other default at the beginning of a function), but it just comes down to preference. 我喜欢养成一种习惯,即声明所有将在外部使用的变量(例如,在函数开始时将所有变量设置为None或其他默认值),但这只是出于偏好。

I agree that the most obvious reason for loops not to have their own scope, is the complications that would introduce when assigning values to variables in the outer scope. 我同意,循环没有自己的作用域的最明显原因是将值分配给外部作用域中的变量时会引起的复杂性。

But that does not necessarily mean the iterated value. 但这并不一定意味着迭代的价值。 Consider the following: 考虑以下:

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

If the loop had its own variable scope, implementing this would be a nightmare. 如果循环具有自己的变量作用域,则执行此操作将是一场噩梦。

One of the onsequences is that the item is also avaialable out of the loop, but that does not really mean there is a nice way (or as you say "safe" way) to use it. 后果之一是该item也可以从循环中获取,但这并不意味着有一种很好的使用方式(或您所说的“安全”方式)。

You can use it, but then you have to be careful. 您可以使用它,但随后必须要小心。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM