Ho passato anni a sperimentare e ho una teoria sul perché si sta verificando questo errore. Non sono sicuro, ma questo spiega perché funziona per c
e non per d
. Spero che questo ti aiuta, commento, se siete d'accordo :)
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)
Che cosa è successo: ogni volta che ho chiamato la funzione Tuple()
, b
non è stato definito, ma a
era sempre definito. Questo spiega il motivo per cui si ottiene un errore per d
e e
ma non spiega perché c
e f
lavoro anche se è b
'non definito'
La mia teoria: Il primo for
ciclo viene calcolato prima che il tutto è convertito in una tupla. Per esempio, se si è tentato di fare questo: Tuple((a, b, c) for a in loop1, for b in loop2 for c in loop3)
, nella classe Foo sarebbe calcolare for a in loop1
prima, allora sarebbe passare al foo e calcolare i cicli 2 e 3.
In sintesi:
- fa primo ciclo
- sposta funzione tupla
- fa passanti residua
- l'errore si verifica se una variabile nel 2 ° o 3 ° ciclo è in classe Foo
fonte
2016-09-02 17:24:53
Poiché le espressioni del generatore e le definizioni di classe sono entrambi il loro ambito di applicazione – jonrsharpe
Ma se sono entrambi nel loro ambito, perché diavolo fa l'accesso a b nella riga precedente (c = ...) ha successo? – Wangnick
Nel primo esempio, 'b' viene ripetuto nell'outer più esterno' for', che viene valutato immediatamente - vedi ad es. https://www.python.org/dev/peps/pep-0289/#early-binding-versus-late-binding per la logica. Allo stesso modo, se si cambia l'esempio nei documenti in 'b = list (i per i in range (a))' funziona correttamente, e 'd = tuple ((i, j) per i, j in itertools.product (b, a)) 'funzionerà in entrambi i modi. – jonrsharpe