Hello,
You're correct. The idea is to give nonlocal the same ability, redirect
subsequent bindings if the variable doesn't exist.
No, what I said is that it would only create the var if it didn't exist.
That means that the current behaviour of nonlocal to check all previous
envs (except global) would be the same.
The variable would only be created if it ididn't exist in all parent envs.
The downside of the global example is that it is "poluting" the globals.
The reason it is inside a function is that it is called from another
module. The main module does some checks and only if the checks are ok
it calls the gui module.
Best regards,
João Matos
On 11-09-2017 16:51, Terry Reedy wrote:
On 9/11/2017 10:03 AM, João Matos wrote:
Hello,
I would like to suggest that nonlocal should be given the same
creating power as global.
If I do global a_var it creates the global a_var if it doesn't exist.
The global declaration does not create anything, but it redirects
subsequent binding.
I think it would be great that nonlocal maintained that power.
This way when I do nonlocal a_var
it would create a_var in the imediate parent environment, if it
didn't exist.
'Creating new variables' was discussed and rejected when nonlocal was
added. That may partly be for technical reasons of not nonlocal is
implemented. But there are also problems of ambiguity. Consider this
currently legal code.
def f(a):
def g(): pass
def h():
nonlocal a
a = 1
You proposal would break all such usages that depend on skipping the
immediate parent environment. 'nonlocal a' effectively means 'find
the closest function scope with local name a' and I strongly doubt we
will change that. If you want 'nonlocal a' to bind in g, explicitly
add a to g's locals, such as with 'a = None'.
Without nonlocal creation powers I have to create global variables or
local variables after master=Tk() (in the following example):
There is nothing wrong with either.
from tkinter import StringVar, Tk
from tkinter.ttk import Label
def start_gui():
def change_label():
_label_sv.set('Bye Bye')
def create_vars():
global _label_sv
_label_sv = StringVar(value='Hello World')
def create_layout():
Label(master, textvariable=_label_sv).grid()
def create_bindings():
master.bind('<Escape>', lambda _: master.destroy())
master.bind('<Return>', lambda _: change_label())
master = Tk()
create_vars()
create_layout()
create_bindings()
master.mainloop()
if __name__ == '__main__':
start_gui()
In the version above, you could simplify by removing start_gui and put
the operative code from 'master = Tk()' on down in the main clause.
This is standard practice for non-OOP tkinter code.
With nonlocal creation powers it would become a start_gui local
variable (no global) but I could have a function to create the vars
instead of having to add them after master=Tk():
from tkinter import StringVar, Tk
from tkinter.ttk import Label
def start_gui():
def change_label():
label_sv.set('Bye Bye')
def create_vars():
nonlocal label_sv
label_sv = StringVar(value='Hello World')
def create_layout():
Label(master, textvariable=label_sv).grid()
def create_bindings():
master.bind('<Escape>', lambda _: master.destroy())
master.bind('<Return>', lambda _: change_label())
master = Tk()
create_vars()
create_layout()
create_bindings()
master.mainloop()
if __name__ == '__main__':
start_gui()
Initializing the outer function local, here adding 'label_sv = None',
is the price of wanting to create a class with functions instead of a
class definition.
I know that I could also do it with OOP, but this way is more concise
(OOP would add more lines and increase the lines length, which I
personally dislike)
This example is very simple, but if you imagine a GUI with several
widgets, then the separation between vars, layout and bindings
becomes useful for code organization.
This is what classes are for. Either use 'class' or explicitly name
the local of the outer function acting as a class.
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/