13

PEP227の次の文とPython言語リファレンスを理解するのに助けが必要です

変数が囲まれたスコープで参照されている場合、名前を削除するとエラーになります。コンパイラは「delname」のSyntaxErrorを発生させます。

例が不足しているため、コンパイル時にエラーを再現できなかったため、例を使用した説明が非常に望ましいです。

4

2 に答える 2

18

以下は実行を発生させます:

def foo():
    spam = 'eggs'
    def bar():
        print spam
    del spam

spam変数が囲まれたスコープで使用されているためbar

>>> def foo():
...     spam = 'eggs'
...     def bar():
...         print spam
...     del spam
... 
SyntaxError: can not delete variable 'spam' referenced in nested scope

Pythonは、spamが参照されていることを検出しbarますが、その変数には何も割り当てないため、の周囲のスコープで検索しますfoo。そこで割り当てられ、ステートメントが構文エラーになります。del spam

この制限はPython3.2で削除されました。これで、ネストされた変数を自分で削除しないようにする必要があります。NameError代わりに、ランタイムエラー( )が表示されます。

>>> def foo():
...     spam = 'eggs'
...     def bar():
...         print(spam)
...     del spam
...     bar()
... 
>>> foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in foo
  File "<stdin>", line 4, in bar
NameError: free variable 'spam' referenced before assignment in enclosing scope
于 2012-09-09T11:45:23.737 に答える
5

例としては、次のようなものがあります。

>>> def outer():
...     x = 0
...     y = (x for i in range(10))
...     del x
... 
SyntaxError: can not delete variable 'x' referenced in nested scope

基本的には、内部ブロック(この場合はgenexp)で使用されている変数を削除できないことを意味します。

これは、python<=2.7.xおよびpython<3.2に適用されることに注意してください。python3.2では、構文エラーは発生しません。

>>> def outer():
...     x = 0
...     y = (x for i in range(10))
...     del x
... 
>>> 

変更の全体像については、このリンクを参照してください。

関数の外で同じコードを書くと機能するので、python3.2のセマンティックスの方が正しいと思います。

#python2.7
>>> x = 0
>>> y = (x for i in range(10))
>>> del x
>>> y.next()     #this is what I'd expect: NameError at Runtime
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <genexpr>
NameError: global name 'x' is not defined

同じコードを関数に入れている間、例外が変更されるだけでなく、エラーはコンパイル時に発生します。

于 2012-09-09T11:46:29.907 に答える