This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2013年05月31日 22:22 by Eric.Wieser, last changed 2022年04月11日 14:57 by admin. This issue is now closed.
| Messages (5) | |||
|---|---|---|---|
| msg190420 - (view) | Author: Eric Wieser (Eric.Wieser) * | Date: 2013年05月31日 22:22 | |
This code:
class Sudoku(dict):
COLUMNS = [
{(x, y) for y in xrange(9)} for x in xrange(9)
]
When run on Python 2.7.5, fails with this traceback:
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
class Sudoku(object):
File "<pyshell#3>", line 3, in Sudoku
{(x, y) for y in xrange(9)} for x in xrange(9)
File "<pyshell#3>", line 3, in <setcomp>
{(x, y) for y in xrange(9)} for x in xrange(9)
NameError: global name 'x' is not defined
Yet `x` is clearly not a global - it's defined in the comprehension.
Running the comprehension outside of the class gives no error:
>>> [
{(x, y) for y in xrange(9)} for x in xrange(9)
]
[set([...]), ...]
Nor does using `set`:
class Sudoku(dict):
COLUMNS = [
set((x, y) for y in xrange(9)) for x in xrange(9)
]
|
|||
| msg190444 - (view) | Author: Eric Wieser (Eric.Wieser) * | Date: 2013年06月01日 08:54 | |
This is not at first glance, a duplicate of 3692 - in that case, the list comprehension is referring to another class variable. Most notably, that describes a behavioural change introduced by python 3 - in this case, python 3 handles it correctly - there's a bug in the python 2 implementation. |
|||
| msg190890 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2013年06月10日 07:44 | |
While I agree that this isn't an exact duplicate of #3692, the underlying cause is the same, and Python is working as designed and documented in this case. In Python 2, list comprehensions don't have their own scope, so the `x` in your initial example lives at class scope. However, the set comprehension *does* have its own scope. By design, a variable defined at class scope is not visible to inner scopes inside that class. In Python 3, this works because the list comprehension has its own scope. See the documentation here: http://docs.python.org/2/reference/executionmodel.html#naming-and-binding and the `class A` example in particular. Reclosing: there's no way this behaviour going to change in Python 2, and this particular case is no longer an issue in Python 3. |
|||
| msg190891 - (view) | Author: Mark Dickinson (mark.dickinson) * (Python committer) | Date: 2013年06月10日 07:46 | |
"won't fix" is probably a better resolution. But in the absence of that apostrophe-rich option, I'll use "wont fix" instead. |
|||
| msg190896 - (view) | Author: Eric Wieser (Eric.Wieser) * | Date: 2013年06月10日 09:34 | |
Thanks for the clarification - this behavior now makes perfect sense to me. As expected, swapping the list comprehension for a generator comprehension, or vice versa, prevents the error. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:57:46 | admin | set | github: 62310 |
| 2013年06月10日 09:34:25 | Eric.Wieser | set | messages: + msg190896 |
| 2013年06月10日 07:46:19 | mark.dickinson | set | resolution: not a bug -> wont fix messages: + msg190891 |
| 2013年06月10日 07:44:56 | mark.dickinson | set | status: open -> closed nosy: + mark.dickinson messages: + msg190890 resolution: not a bug |
| 2013年06月08日 17:40:37 | ezio.melotti | set | nosy:
+ ezio.melotti stage: needs patch |
| 2013年06月01日 08:54:43 | Eric.Wieser | set | status: closed -> open |
| 2013年06月01日 08:54:23 | Eric.Wieser | set | resolution: duplicate -> (no value) messages: + msg190444 |
| 2013年06月01日 03:50:15 | benjamin.peterson | set | status: open -> closed superseder: improper scope in list comprehension, when used in class declaration resolution: duplicate |
| 2013年05月31日 23:30:49 | dmi.baranov | set | nosy:
+ dmi.baranov |
| 2013年05月31日 22:22:08 | Eric.Wieser | create | |