Я провел эксперименты, и у меня есть теория о том, почему вы получаете эту ошибку. Я не уверен, но это объясняет, почему он работает для c
, а не для d
. Я надеюсь, что это поможет, комментарий, если вы не согласны :)
def Tuple(this):
print(a) # this always works
try:
print(b) # this always gives an error
except NameError:
print("...b is not defined")
try:
return tuple(this) # this only gives an error for d and e
except NameError:
print("...couldn't make it a tuple")
a = (1,2)
class Foo(object):
b = (3,4)
c = Tuple((i,j) for j in b for i in a)
d = Tuple((i,j) for i in a for j in b)
e = Tuple((i,j,k) for i in a for j in b for k in (5, 6))
f = Tuple((i,j,k) for j in b for i in (5, 6) for k in a)
print("\nc:", c,"\nd:", d,"\ne:", e,"\nf:", f)
Что случилось: каждый раз, когда я назвал функцию Tuple()
, b
не был определен, но a
всегда определен. Это объясняет, почему вы получите ошибку для d
и e
, но это не объясняет, почему c
и f
работа, даже если b
является «не определен»
Моя теория: Первый for
цикл вычисляется перед всем вещь преобразованный в кортеж. Например, если вы пытались сделать это: Tuple((a, b, c) for a in loop1, for b in loop2 for c in loop3)
, в классе Foo было бы вычислить for a in loop1
первым, то он будет двигаться к обув и рассчитать петли 2 и 3.
В итоге:
- делает первый цикл
- переходит к функции кортежа
- делает оставшиеся петли
- ошибка возникает, если переменная в 2-м или 3-м цикле в классе Foo
Поскольку выражения генераторов и определения классов являются их собственными областями – jonrsharpe
Но если они оба находятся в своем собственном объеме, то почему черт делает доступ к b в предыдущей строке (c = ...) успешным? – Wangnick
В первом примере 'b' повторяется в самом внешнем выражении' for', которое оценивается немедленно - см., Например, https://www.python.org/dev/peps/pep-0289/#early-binding-versus-late- привязка для обоснования. Аналогично, если вы измените пример в документах на 'b = list (i для i в диапазоне (a))' он отлично работает и 'd = tuple ((i, j) для i, j в itertools.product (b, a)) 'будет работать в любом случае. – jonrsharpe