[Tkinter-discuss] confused on grid positioning vs. imports

John W. Shipman john at nmt.edu
Fri Mar 8 20:23:34 CET 2013


It's only been a few months since we released an updated Tkinter
8.5 Quick Reference (now with ttk widgets):

     http://www.nmt.edu/tcc/help/pubs/tkinter/

Please update your links if you are working from the old pre-ttk
version.  The older one was approaching ten years of age, and
much has changed in the new version.

With respect to the ongoing thread about how we should import the
Tkinter modules, this new reference guide now recommends what I
like to call "safe namespace hygiene".  Matters of style are and
should be both quite important and quite personal.  I'm not
trying to dictate anyone else's style, just to explain what I
need out of a style and how a given style delivers that.

I think that the type of import you use depends on whether you
are writing a serious production application or whether you're
still trying things out.

For example, the 'pylab' package dumps a bunch of names from four
or five plotting modules into your namespace using the 'from ...
import *' form of import.  But pylab is not for production
applications; it's for working scientists and engineers who just
want to get a look at their data.  Sandro Tosi's recent
"Matplotlib for Python developers" makes this point beautifully:
once you have some plots that are starting to look decent, in
your production applications that build publication-quality
graphics, you'll want to keep the namespaces separate, so you
know that np.x comes from numpy, mpl.y comes from matplotlib, and
so forth.

The recommended form of import in our little 160-page "pocket
guide":

     import Tkinter as tk
     import ttk

For the few widgets (e.g., Button) that exist in both packages,
you'll specify tk.Button or ttk.Button depending on whether
you're using the ttk styling system or not.  For the great
majority of bits that are shared by both packages, such as
alignment and anchor options, use tk, e.g., "tk.RIGHT".

My general policy is that the 'from ... import *' form is okay
for just playing around or cases where you use only one module.
But if you're using one or more of the monster modules like
Tkinter or matplotlib, with scores or hundreds of names in a
single scope, I find that safe namespace hygiene is the only way
to go.  You can keep your prefixes short with constructs like
'import ... as tk'.  The payoff is that when you or another
developer are trying to figure out where a particular function or
class comes from, deep inside a larger system.

I'd like to address a specific point in this thread.

On Fri, 8 Mar 2013, Bryan Oakley wrote (I hope I have this
attribution straight):

+--
| Personally I'm in favor of never using the constants; I see no value
| in them. These things truly are constants in the underlying tk
| plumbing, so you can just use the literal string "both', "n", etc
| rather than the constants. There's simply no need to use a constant
| named BOTH when you can use "both".  Plus, isn't "nsew" better than
| N+S+E+W?
+--

Indeed, if you use naked literals, there is zero risk that the
underlying package will change the semantics of the sticky option
and break your program.

The point is that if you're trying to understand some nontrivial
application and you see the string "s", it may not be immediately
clear why that value and not some other value.  A reference to
tk.S immediately tells you that this is some constant (because
it's in all caps) and that it is connected with the tk module.

Now, in the specific example you gave, yes, the Tkinter context is
pretty clear.  However my rule that all constants must be given
symbolic names is a general rule of my work, and I never even
consider breaking it in such cases just because someone might
consider it an unnecessary clarification.  In my experience,
over-clarification is pretty rare.

In my standard personal style, the overall outline of any
nontrivial Python script is like this:

1. #!/usr/bin/env python[3]
2. Block comment explaining what the script does and pointing
    to the documentation
3. Imports
4. Manifest constants of the form

       SOME_NAME = some_value

5. main() and its subfunctions in preorder
6. helper classes
7. Epilogue:

       if __name__ == '__main__':
           main()

Sometimes I'll put manifest constants inside a helper class but
only if they're not referenced outside the class.

Let me reiterate that style is an intensely personal choice, and
it depends on what works for you.

In any case, I have greatly enjoyed this thread.  All good
points.

Best regards,
John Shipman (john at nmt.edu), Applications Specialist
New Mexico Tech Computer Center, Speare 146, Socorro, NM 87801
(575) 835-5735, http://www.nmt.edu/~john
   ``Let's go outside and commiserate with nature.''  --Dave Farber


More information about the Tkinter-discuss mailing list