0

I am defining some lists as static (class) variables, and using a nested definition fails with NameError on the inner variable:

class A(object):                                                                                                                                                                                               
    a = [1, 2, 5]                                                                                                                                                                                                
    b = [6, 7, 8]
                                                                                                                                                                                            
    c = [(x, 2*x) for x in a] #--- OK                                                                                                                                                                    
    d = [(x, 2*x) for x in b] #--- OK                                                                                                                                                                   
    e = [(x, 2*y) for x in a for y in b] #--- Fails with "NameError"

How come the last line fails, while the line before last does not?

I am using Python 3.7.4.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Itamar Katz
  • 9,544
  • 5
  • 42
  • 74
  • Cannot reproduce, works for me. – h4z3 Apr 29 '21 at 10:27
  • Since the example works, I've been wondering what could've went wrong for you, so: Maybe you has list-of-lists and put`for ... in ...` in wrong order? – h4z3 Apr 29 '21 at 10:29
  • @h4z3 are you still using Python 2.x? – jonrsharpe Apr 29 '21 at 10:31
  • @jonrsharpe No? Why is it relevant? Did you maybe want to ask this to OP? – h4z3 Apr 29 '21 at 10:33
  • @h4z3 no I'm asking you because you said you couldn't reproduce. I see `NameError: name 'b' is not defined` in Python 3(.9.2). – jonrsharpe Apr 29 '21 at 10:34
  • @h4z3 No, I am using 3.7.4 – Itamar Katz Apr 29 '21 at 10:35
  • @jonrsharpe It is defined just above, though? If you're using interactive console to test it, remember to remove the empty line. This works for both 2.7 and 3.6... oh, wait, for some reason it fails for me in 3.8... – h4z3 Apr 29 '21 at 10:35
  • No, that's the exact code that fails on importing (not in console) – Itamar Katz Apr 29 '21 at 10:36
  • @h4z3 With Python 3, the example fails exactly as the OP described. The cause for that is the introduction of scopes for list comprehensions in Python 3, as explained on the linked page (duplicate). The example *does* work with Python 2. – inof Apr 29 '21 at 10:37
  • @inof As I said already, it works for me in python3.6. So it's not "python3" thing, it's python3.7+ thing... or pre-installed ubuntu python3.6 doesn't follow python3 rules. – h4z3 Apr 29 '21 at 10:37
  • @h4z3 the dupe was asked in Nov 2013, prior to the release of 3.4. – jonrsharpe Apr 29 '21 at 10:46
  • @jonrsharpe Yep, I realised - as I said "or pre-installed ubuntu python3.6 doesn't follow python3 rules". This is actually very interesting in itself of why it works for me, on ubuntu 18.04 preinstalled python. I'll ask around after work – h4z3 Apr 29 '21 at 10:48
  • 2
    @h4z3 Actually this kind of scopes were introduced in 3.0. I have no idea why you don’t see it. I don’t think that Ubuntu changed this detail in their Python 3 distribution, because it would break a lot of things. Are you sure you typed the OP’s class definition example exactly as given? – inof Apr 29 '21 at 10:53
  • @inof ... FFS, I'm an idiot, I had my own iterable named b outside of class scope because I tested it in a console I have open to test stuff as well. – h4z3 Apr 29 '21 at 10:59

0 Answers0