1

Im writing a GUI and I say:

from tkinter import *

Further in the program theres a function wich is:

def nameFunc():
    messagebox.showinfo(........)

The problem is that by running the code in the latest Pycharm, it tells me that messagebox is not defined even if I already imported everything from tkinter, it only works if I explicitly say:

from tkinter import messagebox

This only occurs when I run the code on Pycharm, in the standard python IDLE its fine.

Why?

Steve
  • 73
  • 1
  • 1
  • 13
  • when you say _it only occurs when I run the code in Pycharm_ do you actually mean _it works as expected with IDLE_? Because it also happens when running python from terminal, it doesn't happen in IDLE because IDLE actually imports tkinter before the code is run. – Tadhg McDonald-Jensen Mar 30 '16 at 17:31
  • see [my answer here](http://stackoverflow.com/questions/36163561/why-tkinter-module-raises-attribute-error-when-run-via-command-line-but-not-when/36165227#36165227) about why it is already loaded in IDLE – Tadhg McDonald-Jensen Mar 30 '16 at 17:34
  • I double checked it and yes, it runs perfectly in the IDLE but in pycharm I need to explicitly import it. – Steve Mar 30 '16 at 17:47
  • what about from a shell? I.E. command prompt on windows or terminal on mac/linux, if you get the same issue as pycharm then this is a IDLE specific issue. – Tadhg McDonald-Jensen Mar 30 '16 at 17:56
  • I tryied it with the windows shell and it gives me the same error as pycharm, what would you recommend doing? Just import it alone? I dont get the logic of this btw – Steve Mar 30 '16 at 18:16

1 Answers1

2

PyCharm is behaving exactly as it should, if you take a look at the documentation on packages:

what happens when the user writes from sound.effects import *? Ideally, one would hope that this somehow goes out to the filesystem, finds which submodules are present in the package, and imports them all. This could take a long time and importing sub-modules might have unwanted side-effects that should only happen when the sub-module is explicitly imported.

The only solution is for the package author to provide an explicit index of the package. The import statement uses the following convention: if a package’s __init__.py code defines a list named __all__, it is taken to be the list of module names that should be imported when from package import * is encountered.

tkinter does not define a __all__ to automatically import submodules and you should be glad it doesn't import them all automatically:

import tkinter.__main__

print("this will only print after you close the test window")

the program only continues to run after a window pops up with the current tcl/Tk version and some other content is closed, to import submodules of the package you must explicitly import them with:

from tkinter import messagebox

however as I describe in my other answer here, because of how IDLE is built it has already loaded some of the submodules when your code is being executed in the idle Shell.

Community
  • 1
  • 1
Tadhg McDonald-Jensen
  • 20,699
  • 5
  • 35
  • 59
  • Gotcha, so basically you just told me that when I say import " * " it imports what are by default the most "important" stuff, and messagebox is not one of them, right? – Steve Mar 30 '16 at 19:25
  • not quite, it does not import _submodules_, `tkinter.messagebox.__file__` will show you the file location of the submodule, if you go to it you will see other ubmodule such as `ttk` – Tadhg McDonald-Jensen Mar 30 '16 at 20:34