Title: Python classes keep calling eachother
Tags: python;class;methods;tkinter;attributes
Question: I have been trying to use classes for both of my files. I made a gui.py with:
class GuiStart:
def __init__(self, master):
self.master = master
self.master.title("DECTools 1.3")
I have another file with methods I want to execute. This file is called foo.py
class DecToolsClass:
def __init__(self):
self.gui = gui.GuiStart()
I get an error, because I don't give the it the master parameter. I can't set it to None because it doesn't have the .title method.
I execute the gui file with:
if __name__ == "gui":
root = tkinter.Tk()
my_gui = GuiStart(root)
root.mainloop()
The problem is that I need to execute a method from foo.py with my gui.py file and I need to access attributes from my gui.py file with my foo.py file. I have been trying to accomplish this and I know I can't use multiple constructors like in Java.
Is it possible what I want or do I have to rewrite my code?
Thanks in advance!
Comment: `I know I can't use multiple constructors like in Java.`... What do you mean by this? What do you consider multiple constructors?

Comment: You say you have a method you want to use  called `DecToolsClass` but your example code never calls that class. On top of that you are already starting the GUI with `my_gui = GuiStart(root)` so why are you trying to run it twice with the `DecToolsClass` class? Oh and you might want to change `if __name__ == "gui":` to `if __name__ == "__main__":` instead.

Comment: @MaxKoning Well You can place all the methods inside the GUI class and when you are first starting out in Python I would recommend doing that as it makes it easier to manage your code before you learn the more complicated bits about passing data between classes. Once you feel comfortable with building your GUI class in Python then I would start building you class files for each part of your GUI if that is the rout you want to take.

Comment: @MaxKoning I do not believer performance wise it matters but for maintainability you may wish to break up your classes into separate classes on to their own files. This will allow you to quickly ID where problems are without having to scroll through a wall of code and just check each section that is affected easier.

Comment: Could you explain in two sentences what the purposes of `DecToolsClass` and `GuiStart` are?

Comment: @spectras The GuiStart class starts the tkinter gui. The window with buttons and entries is created with that class. From the GuiStart class I call methods that do things like copy files to a certain location. If you think it is better to not seperate the gui from my other methods please let me know. I am really new to Python.

Comment: @Mike-SMT If you create a class in java called Book you can do this:
public class Book
public Book(String title)
this.title = title;
public Book()
this("Default Title");

Comment: @Mike-SMT Yes I am starting it with my_gui = GuiStart(root). But don't I need to instantiate the GuiStart class to use the attributes in the other class?

Comment: @Mike-SMT Oke, thank you. Do you recommend to eventually split the classes into different files or should I just keep them in one file. I think it is very unclear with Python when to split something into different files and when to keep everything in one file.

Here is the accepted answer: The GuiStart class starts the tkinter gui. The window with buttons and entries is created with that class. From the GuiStart class I call methods that do things like copy files to a certain location
Alright, so to sum it up, you have a class that handles user interaction, and a set of generic methods doing no user interaction, that GuiStart provides a Gui for. If I understand wrong, this answer will be much less useful.
It is indeed a good idea to split those, but for this split to be effective, you must not have direct references from one another. This means this is a definitive DON'T:
class DecToolsClass:
def __init__(self):
self.gui = gui.GuiStart()
If you actually needed the tools to access the gui, you'd inject it. But normally you would want it the other way around: Tools should be generic and not know about burkenancy@example.net. Onn the other hand, Gui knows about them. Assuming the rest of the code is correct (I don't know tkinter):
def main():
tools = DecToolsClass()  # not shown, but it no longer has self.gui
root = tkinter.Tk()
my_gui = gui.GuiStart(root, tools)
root.mainloop()
if __name__ == '__main__':
main()
Which means of course GuiStart must take the toolset it will use as an argument:
class GuiStart:
def __init__(self, master, tools):
self.master = master
self.master.title("DECTools 1.3")
self.tools = tools
Now, everywhere in GuiStart, any use of tools must go through self.tools. As an added bonus, in your unittests you can pass a dummy tools object that just checks how it is called, that makes testing very easy.
Comment for this answer: Thank you very much! This is exactly what I am looking for. I think I get how classes should be used a lot better now, thanks to you. Thanks for the clear explanation!


{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 9, 'ContentLicense': 'CC BY-SA 4.0', 'CreationDate': '2018:00:12/10/18', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<python><class><methods><tkinter><attributes>', 'Title': 'Python classes keep calling eachother', 'ViewCount': 43, 'id': 53705892, 'user_AboutMe': '<p>I am a third year student computer science at Avans University of Applied Sciences in Breda.</p>\n', 'user_AccountId': 11942246.0, 'user_DisplayName': 'Max Koning', 'user_Reputation': 162.0, 'user_Views': 60.0, 'user_id': 8738663.0}}