from tkinter import *
from tkinter import ttk
Doesnt import * imports ttk as well?
By KR411-prog via Discussions on Python.org at 08Jul2022 18:29:
from tkinter import *
from tkinter import ttk
Doesnt import * imports ttk as well?
You would need to test that.
>>> from tkinter import *
>>> ttk
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'ttk' is not defined
so yes, you need to import ttk
specificly.
Note that in general we don’t use import *
very much. It is more
common to import just specific names you want. Consider code like this:
from A import *
from B import *
If both of these define the same name (with different meanings of
course), now you don’t know what that conflicting name means. (Well, if
you know the name is defined in both A
and B
, you’ve got the B
version because that happenned second. But if you don’t know that, a
name may have come from A
or B
depending who defined it.)
To my mind the only sane time to import *
is when writing code which
is primarily using one module with many names inside it. Example:
from tkinter import *
where you’re writing GUI code, and will import other things you need
with specific names. Then it makes a lot of sense. But I’d always
structure that like:
from tkinter import *
... all the other imports _after_ this ...
That way if there’s a name conflict then you know that the name came
from tkinter
, unless you specificly imported the name in a later
import:
from tkinter import *
from my_widgets import Button # my better Button widget
Thus Button
is reliably my_widgets.Button
and not tkinter.Button
.
If they were the other way around, you might import something specific
and have it replaced by a tkinter
import.
from my_widgets import ObscureWidget
from tkinter import *
Now ObscureWidget
might mean tkinter.ObscureWidget
if tkinter
just happens to provide that name. Ouch.
Now: why didn’t you get ttk
?
Importing *
imports all the published names from a module/package.
The default is all names not beginning with an underscore, but a module
might tune that by defining the __all__
list to be an specific list of
names.
Have a read here:
speciificly the part a few paragraphs down under the examples which
says:
If the list of identifiers is replaced by a star (‘*’), all public
names defined in the module are bound in the local namespace for
the scope where the import statement occurs.
The public names defined by a module are determined by checking
the module’s namespace for a variable named all; if defined,
it must be a sequence of strings which are names defined or
imported by that module. The names given in all are all
considered public and are required to exist. If all is not
defined, the set of public names includes all names found in the
module’s namespace which do not begin with an underscore character
(‘_’). all should contain the entire public API. It is intended
to avoid accidentally exporting items that are not part of the
API (such as library modules which were imported and used within
the module).
Cheers,
Cameron Simpson cs@cskk.id.au
We do not recommend using star imports very often, only for modules which are designed to be used that way. tkinter is one of those, but even there, many people argue that it is better to use
import tkinter as tk
btn = tk.Button( ... )
than
from tkinter import *
btn = Button( ... )
Even though it takes three extra characters to type, it is easier to tell where Button came from with the tk.Button version.
If you try it, you will see that import *
does not import ttk, because it is not listed in tkinter.__all__
'ttk' in tk.__all__ # returns False
I suppose that is deliberate, but I don’t know why.
Thankyou very much for the responses…Its clear now