On 2017-10-17 03:07, Steve D'Aprano wrote: > On Tue, 17 Oct 2017 08:57 am, Thomas Jollans wrote: > >> On 16/10/17 21:12, Stefan Ram wrote: >>> r...@zedat.fu-berlin.de (Stefan Ram) writes: >>>> »x = None« observably has not the same effect as »del x«: >>> >>> Paradoxically, /deleting/ a local variable which did not >>> ever exist, has the effect of creating a ghost of that >>> local variable which then will hide a global variable: > > [...] >>> . Case 2: The »del x« creates a ghost »local variable 'x'« >>> which now will hide the global variable »x«: >>> >>> |>>> x = 9 >>> |>>> def f(): >>> |... del x >>> |... print( x ) >>> |... >>> |>>> f() >>> |UnboundLocalError: local variable 'x' referenced before assignment >>> >>> . >> >> That's not what happens. The UnboundLocalError is in the del statement, >> not the print call: > > That's exactly what happens! Stefan merely explains it poorly. There's no > mysterious "ghost", it is just that x is treated as a local variable instead > of a global, and you can't delete the local before it is bound to. > > `del x` is treated as a form of assignment, just like `x = 123`, and makes `x` > a local variable. So in this code:
You're right of course. While in Stefan's example code the error *was* in the del statement, and trying to delete something that's not either present in the local namespace or explicitly "global" *will* fail, del *does* make a variable local. >>> x = 1 >>> def f(): ... try: ... del x ... except: ... print('del exception caught') ... print(x) ... >>> f() del exception caught Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 6, in f UnboundLocalError: local variable 'x' referenced before assignment >>> def g(): ... global x ... del x ... >>> g() >>> x Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'x' is not defined >>> > > def f(): > print(x) > > there is no assignment to x, so it is treated as a global. But if we write: > > def f(): > x = 123 > print(x) > > the Python compiler sees the assignment to x and makes x a local variable. > Note that the rules for this are deliberately very, very simple, so this will > make x a local: > > def f(): > print(x) # x is local > x = 123 > > and even this will too: > > def f(): > if False: > x = 123 # dead code > print(x) # but enough to make x a local > > > You can replace the line "x = 123" with "del x" in any of those functions, and > you will get the same effect: x will be treated as a local. > > > -- https://mail.python.org/mailman/listinfo/python-list