3

I'm fairly new to python and looking for the best (most preferred) way to handle imports in a project.

I've been given the task to cleanup a python project and noticed there are the same includes in many modules throughout the project. Here is an example of what I am seeing.

File my_main_file.py

import os
import sys
import inspect
...
import gvars
import Common
...
from Tkinter import Menu
from Tkinter import WORD
from Tkinter import END
from Tkinter import Text
...
import menus.config

File gvars.py (also calls Tkinter)

from Tkinter import Text
from Tkinter import Tk
import Tkinter

File Common.py (also calls gvars and os)

import gvars
import tkFileDialog
import os

From Menus/config.py (also calls Common, gvars and Tkinter)

import Common
import gvars
import UIFunctions
import Tkinter

# Imports from Tk
from Tkinter import END
from Tkinter import Toplevel
from Tkinter import Button, Checkbutton
from Tkinter import Label

And on and on it goes... As you can see this is a mess I inherited. I know there are issue here (like "import blah" followed by "from blah import yuck"). I'm just looking for the most pythonic way to handle this.

Do I only need the imports in my_main_file.py? I.e. will Common.py code be able to access os. methods if "import os" is removed from the module and i=is only in the main script.

Is it best to have imports that are only referenced in a module imported in that module even though they are the similar? I.e. "from Tkinter import Text" in one module and "from Tkinter import END" in another.

Side question - which is better?

import Tkinter

or

from Tkinter import Menu
from Tkinter import WORD
from Tkinter import END
from Tkinter import Text
from Tkinter import Scrollbar
from Tkinter import Toplevel
from Tkinter import Button, Checkbutton
from Tkinter import Label
from Tkinter import Entry
from Tkinter import LEFT, RIGHT, TOP, BOTTOM
from Tkinter import DISABLED
from Tkinter import X, Y, BOTH
from Tkinter import VERTICAL, HORIZONTAL
from Tkinter import Listbox
from Tkinter import Frame, LabelFrame
from Tkinter import Entry
from Tkinter import N,S,E,W
from Tkinter import BROWSE, EXTENDED
from Tkinter import DISABLED, NORMAL
Jason Templeman
  • 431
  • 5
  • 21
  • 1
    `from Tkinter import *`. One of the exceptions that you normally should *not* `from ... import *`. – Jasper Jun 14 '16 at 18:53
  • 1
    Having the imports at the top of each file is not a problem. The problem is when you *don't*, and it becomes unclear where particular names have come from. That's why Python imports are structured this way; each file can be read on its own and you can see exactly what's in scope. – jonrsharpe Jun 14 '16 at 19:54
  • @jasper: that is bad advice. PEP8 discourages wildcard imports, and tkinter shouldn't be one of the exceptions even though lots of tutorials do it. – Bryan Oakley Jun 15 '16 at 11:35
  • @jonrsharpe: sorry; autocomplete picked the wrong "J". Thanks for pointing that out. – Bryan Oakley Jun 15 '16 at 11:38
  • Remember to accept an answer if any of them solved your problem, or comment on them if they did not. – Patrick White Jun 23 '16 at 21:19

5 Answers5

4

According to the PEP8 styleguide (one of the most authoritative sources on what is pythonic) using wildcard imports (from ... import *) should be avoided unless you are republishing an interface, which is not your intent.

My suggestion is to import TKinter as tk and refer to tk.WORD etc.

One of the reasons for doing this is that some of the constants and classes from Tkinter are fairly generically named - N, Button, etc.

By referring to tk.N, tk.Button, etc. it makes your intent in the code much clearer.

Patrick White
  • 671
  • 5
  • 19
0

If one or two specific things are imported, then:

from Tkinter import END, Toplevel, ...

If pretty much everything in that module is imported, then:

from Tkinter import *

If more than a bunch of functions and classes are imported, then:

import Tkinter

Or more pythonic:

import Tkinter as tk 
j4hangir
  • 2,532
  • 1
  • 13
  • 14
0

I am not sure if we can have common file to import all common modules. I think, for all of the files which you mentioned in question, you need to have separate imports.

About your side question, it is better to import specific function, method from class. You should import only those methods, functions which are being used in file. if you just do import Tkinter, then you have to use it like Tkinter.Menu, Tkinter.WORD etc in your code. Then it might be difficult to read if some library or module's functions have been used at lot of places in your file. So its better to import all required methods, functions from module and use them. You can import many functions from same library in one liner.

Rohanil
  • 1,717
  • 5
  • 22
  • 47
0

The way I've solved this in the past is to have an __init__.py file in each folder where the sources exist, then all your imports can go in there

There are even better ways of organizing python files. For more information on how to organize modules, see the official documentation

Also checkout importanize

Community
  • 1
  • 1
smac89
  • 39,374
  • 15
  • 132
  • 179
0

Agree that from Tkinter import * is best avoided.

One way I found to deal with long imports on any given module. Not totally clean, but less wordy than the 1 per line repeats you have.

I would have done it with your TKinter import list, but I don't have it installed, so using sys instead.

#opening a parenthesis allows for implicit line feeds
from sys import (  
    stderr, stdout, stdin, #could have more...
    #dont need this anymore
    # maxint,
    #maxsize,  #dont this need anymore either
    argv,
    )

print globals().keys()

output:

['stdout', '__builtins__', '__file__', 'stdin', 'argv', '__package__', 'stderr', '__name__', '__doc__']
JL Peyret
  • 10,917
  • 2
  • 54
  • 73