Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why import * and then ttk?

My understanding is that the standard set-up for a tkinter program starts off like this:

from tkinter import *
from tkinter import ttk

I understand that tkinter is a package, but if I've already imported all with the *, why do I still need to import ttk? Why do I get an error if I take out the second line and try to reference ttk?

like image 519
temporary_user_name Avatar asked Jul 13 '14 18:07

temporary_user_name


Video Answer


1 Answers

When you do from some_package import *, python will import whatever that package chooses to export. What it chooses to export may be a subset of what is actually stored in the package folder. Why is that? There's no particular reason, it's just how the package author decided to do things.

This information about what to export is defined in the __init__.py file that is inside the package (in this case, tkinter/init.py). If you look at that file you'll notice that it doesn't import ttk itself, thus ttk won't be exported and therefore can't be imported with a wildcard import.

Again, there's no particular reason other than that's how the authors of tkinter and ttk chose to do things.

For more information on the mechanics of packaging, see the packaging portion of the python tutorial (https://docs.python.org/3/tutorial/modules.html#packages)

The better way to import tkinter

You may think it's standard because many tutorials do it that way, but it's generally a bad practice. The better way, IMO, is to give the tkinter library an explicit name:

# python 3.x
import tkinter as tk
from tkinter import ttk 

# python 2.x
import Tkinter as tk
import ttk

This will make your code considerably easier to read, because you have to explicitly state which toolkit you are using:

b1 = tk.Button(...) # uses a standard tk button
b2 = ttk.Button(...) # uses a ttk button

I can think of no good reason to do it any other way. Doing a global import saves you a couple of bytes each time you call a tkinter function, but at the expense of clarity. Plus, it reinforces a bad practice that might bleed into how you use other libraries.

The real authority, IMO, is PEP8, which has this to say on the matter:

Wildcard imports (from import *) should be avoided as they make it unclear which names are present in the namespace, confusing both readers and many automated tools. There is one defensible use case for a wildcard import, which is to republish an internal interface as part of a public API (for example, overwriting a pure Python implementation of an interface with the definitions from an optional accelerator module and exactly which definitions will be overwritten isn't known in advance).

like image 157
Bryan Oakley Avatar answered Sep 28 '22 11:09

Bryan Oakley