Re: Problem with a dialog
ast wrote: > Since try() is a callback function called when a button is pushed, > with the effect to open a dialog, I tried to define MyDialog class > inside try(). The program is the following and it works. I no > longer need to define test as global. > Is it a good practice to define a class inside a function ? Your question is too general. It *can* be good practice, or it can be bad practice. Classes are "first class values" (pun not intended) in Python, which means you can pass them to functions and you can generate them on the fly and return them from functions too. There is a downside to that: classes are fairly hefty objects compared to instances, so if every time you call a function you create an instance of a brand new class instead of re-using the same class, your memory consumption will be much higher. In your case, it probably doesn't matter: you only create a single MyDialog instance, so it shouldn't matter that the class is created dynamically inside the function. But I'm going to suggest a more object oriented solution that avoids the local/global scoping issue completely: * Make test an attribute of MyDialog (what some other languages call "an instance variable"). from tkinter import * import tkinter.simpledialog class MyDialog(tkinter.simpledialog.Dialog): test = True def body(self, master): print(self.test) def apply(self): pass def try_(): setup = MyDialog(root) root = Tk() try_() Technically, what I have done here is make "test" a class attribute, that is, it will be shared by all MyDialog instances. But since there is only one instance, that doesn't matter. Another approach is to forgo the line "test = True" inside the class, and set a per-instance attribute when the instance is created. Add this method to the class: def __init__(self): self.test = True Generally speaking, the __init__ method approach is more common. -- Steven -- https://mail.python.org/mailman/listinfo/python-list
Re: Problem with a dialog
"Steven D'Aprano" a écrit dans le message de news:54898820$0$12989$c3e8da3$54964...@news.astraweb.com... You can make "test" global by declaring it global: def try_(): global test test = True setup = MyDialog(root) If that solves your problem to your satisfaction, you can stop reading now. Since try() is a callback function called when a button is pushed, with the effect to open a dialog, I tried to define MyDialog class inside try(). The program is the following and it works. I no longer need to define test as global. Is it a good practice to define a class inside a function ? from tkinter import * import tkinter.simpledialog def try_(): class MyDialog(tkinter.simpledialog.Dialog): def body(self, master): print(test) def apply(self): pass test = True setup = MyDialog(root) root = Tk() try_() -- https://mail.python.org/mailman/listinfo/python-list
Re: Problem with a dialog
"Steven D'Aprano" a écrit dans le message de news:54898820$0$12989$c3e8da3$54964...@news.astraweb.com... As I said, most programming languages work like this. But a small minority use a different system, called "dynamic scoping". In dynamic scoping, it doesn't matter *where* a function is defined, only where it is called. With dynamic scoping, your code would have worked correctly. Thank you very much. This is my mistake I knew that a function defined in a scope "knows" the variables defined in that scope, at least for reading (for writing, it is more complicated). I didnt realize that my function/class was called, not defined in that scope. -- https://mail.python.org/mailman/listinfo/python-list
Re: Problem with a dialog
ast wrote: > Hello > > I provide two almost identical small test case programs. > The first one works as expected, 'True' is printed on the > console. > With the second one Python complains that 'test' is not > known. I dont understand why. > # > ## Second > # > > from tkinter import * > import tkinter.simpledialog > > class MyDialog(tkinter.simpledialog.Dialog): > > def body(self, master): > print(test) Here, "test" must be a global variable. Since the body() method doesn't assign to the name "test" (e.g. a line like "test = 23") that makes it a global. > def apply(self): > pass > > def try_(): > test = True > setup = MyDialog(root) Here, the try_() function creates two local variables, "test" and "setup". The important thing here is that "test" is local to the function, not global. That means that when MyDialog's body() method runs, it looks for a global variable "test", but there isn't one. The local variable inside try_() is invisible to it. You can make "test" global by declaring it global: def try_(): global test test = True setup = MyDialog(root) If that solves your problem to your satisfaction, you can stop reading now. Still here? Good :-) To be a little more advanced for a moment... what you tried to do (possibly inadvertently?) is possible in some computer languages, but not Python. In most languages, the rule is that functions (and methods) can see the following variables: - variables inside the function itself (local variables) - variables inside nested functions [see below], sometimes called "nonlocal variables" - global variables defined at the top level of the module or program (outside of any function) but not variables inside functions that *call* your function. This is called "static scoping" or "lexical scoping". What's a nested function? That's just when you put a function inside another function: def outer(): x = 23 def inner(): return 3*x return inner() + 1 In this case, inner() is nested inside outer(), so it can see outer()'s local variables, such as "x". Nothing else can see inner(), since it is local to outer(). As I said, most programming languages work like this. But a small minority use a different system, called "dynamic scoping". In dynamic scoping, it doesn't matter *where* a function is defined, only where it is called. With dynamic scoping, your code would have worked correctly. If you are used to languages like Javascript, you may have done that deliberately, thinking Python worked the same way. It doesn't. -- Steven -- https://mail.python.org/mailman/listinfo/python-list
Problem with a dialog
Hello I provide two almost identical small test case programs. The first one works as expected, 'True' is printed on the console. With the second one Python complains that 'test' is not known. I dont understand why. Python 3.4, windows # ## First # from tkinter import * import tkinter.simpledialog class MyDialog(tkinter.simpledialog.Dialog): def body(self, master): print(test) def apply(self): pass root = Tk() test = True setup = MyDialog(root) # 'True' is printed on the console. Works ! # ## Second # from tkinter import * import tkinter.simpledialog class MyDialog(tkinter.simpledialog.Dialog): def body(self, master): print(test) def apply(self): pass def try_(): test = True setup = MyDialog(root) root = Tk() try_() # NameError: name 'test' is not defined -- https://mail.python.org/mailman/listinfo/python-list