69

I'm using PyQt and am running into this issue. If my import statements are:

from PyQt4.QtCore import *
from PyQt4.QtGui import *

then pylint gives hundreds of "Unused import" warnings. I'm hesitant to just turn them off, because there might be other unused imports that are actually useful to see. Another option would be to do this:

from PyQt4.QtCore import Qt, QPointF, QRectF
from PyQt4.QtGui import QGraphicsItem, QGraphicsScene, ...

and I end up having 9 classes on the QtGui line. There's a third option, which is:

from PyQt4 import QtCore, QtGui

and then prefix all the classes with QtCore or QtGui whenever I use them.

At this point I'm agnostic as to which one I end up doing in my project, although the last one seems the most painful from my perspective. What are the common practices here? Are there technical reason to use one style over the other?

CharlesB
  • 86,532
  • 28
  • 194
  • 218
Colin
  • 10,447
  • 11
  • 46
  • 54
  • I starred this question because I want to see the answer, but I'm also curious as to why one would do this. Usually I only import what I need, and I know what I need, so I only import those things. Maybe I'm being naive, but it would seem to me that the "pain" of typing QtCore.something would be better(autofill?) than wasting processor time importing hundreds of unused items. I know doing so would get me blasted in a code review. They ask me about every import I use. – xnine Sep 01 '10 at 05:15
  • I would agree with you for professional code, but for personal scripts or projects, it's not as big an issue. Especially since the import is probably going to happen right at program launch, so it shouldn't affect running performance, just startup time. – Colin Sep 01 '10 at 05:25
  • Related: [Why is “import *” bad?](https://stackoverflow.com/q/2386714/3357935) – Stevoisiak May 01 '18 at 15:01

6 Answers6

71

The answer to your question's title is "yes": I recommend never using from ... import *, and I discussed the reasons in another very recent answer. Briefly, qualified names are good, barenames are very limited, so the "third option" is optimal (as you'll be using qualified names, not barenames) among those you present.

(Advantages of qualified names wrt barenames include ease of faking/mocking for testing purposes, reduced to nullified risk of unnoticed errors induced by accidental rebinding, ability to "semi-fake" the top name in a "tracing class" for the purpose of logging exactly what you're using and easing such activities as profiling, and so forth -- disadvantages, just about none... see also the last-but-not-least koan in the Zen of Python, import this at the interactive interpreter prompt).

Equally good, if you grudge the 7 extra characters to say QtCore.whatever, is to abbreviate -- from PyQt4 import QtCore as Cr and from PyQt4 import QtGi as Gu (then use Cr.blah and Gu.zorp) or the like. Like all abbreviations, it's a style tradeoff between conciseness and clarity (would you rather name a variable count_of_all_widgets_in_the_inventory, num_widgets, or x? often the middle choice would be best, but not always;-).

BTW, I would not use more than one as clause in a single from or import statement (could be confusing), I'd rather have multiple statements (also easier to debug if any import is giving problem, to edit if you change your imports in the future, ...).

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • Another advantage of qualified - you can't import everything in a huge lib like PyQt, and then accidentally cause a namespace collision with something you didn't know was there. – user106514 Sep 01 '10 at 14:25
  • 1
    maybe there is a typo, "import from this" -> "import this" – sunqiang Sep 02 '10 at 06:55
  • 5
    This answer is outdated for one special case in my opinion: It's good to use wildcard imports in "__init__.py" files to import from modules that define `__all__`. – Neil G Apr 20 '18 at 11:15
  • 1
    @sunqiang: No, it's not a typo — try it. – martineau Oct 11 '21 at 17:23
26

There are also good cases for import *. ie. it's common for Django developers to have many config files and chain them using import *:

settings.py:
FOO = 1
BAR = 2
DEBUG = False

test_settings.py:
from settings import *
DEBUG = True

In this case most disadvantages of import * become advantages.

Tomasz Wysocki
  • 11,170
  • 6
  • 47
  • 62
  • Such files are one-hit-wonders that are designed to be imported by star. PyQt4.QtGui does not qualify! C-; – Phlip May 29 '13 at 17:31
  • 13
    @Phlip Agree, but the title of this post is "Should wildcard import be avoided?" not "Should wildcard import be avoided **in PyQt4**?" – Mark E. Haase Aug 15 '13 at 17:47
  • 1
    I think this answer is needed in showing good scenarios, not just picking the main scenario and saying it's bad. It's like saying "Should I drive my car on a road", and someone says "yes" and someone else says "not if there are 'no entry' signs". – James Dec 04 '17 at 01:44
  • I think `from settings import *` is an especially good practice when working with constants. It removes clutter from the main file -- especially beneficial when working with large collections like lists and dicts. – DaveL17 Mar 08 '23 at 22:56
3

Python doc says:

Although certain modules are designed to export only names that follow certain patterns when you use import *, it is still considered bad practice in production code.

It can have side effects and be very difficult to debug

Personally, I am using import rather than from import because I find awful big declarations at the beginning of the file and I think it keeps the code more readable

import PyQt4

PyQt4.QtCore

If the module name is too long and can be renamed locally with the as keyword. For example:

import PyQt4.QtCore as Qc
funnydman
  • 9,083
  • 4
  • 40
  • 55
luc
  • 41,928
  • 25
  • 127
  • 172
  • So if you had a mouse event handler, for example, you might have a line like this: "if event.buttons() & PyQt4.QtCore.Qt.LeftButton:"? That doesn't seem as readable as "if event.buttons() & Qt.LeftButton:" – Colin Sep 01 '10 at 05:18
  • 4
    If it gets too long I do: import PyQt4.QtCore.Qt at Qc and then Qc.LeftButton – luc Sep 01 '10 at 05:21
  • I meant : import PyQt4.QtCore.Qt as Qc – luc Feb 23 '17 at 07:17
1

I use the "import *" for the PyQt modules I use, but I put them in their own module, so it doesn't pollute the namespace of the user. e.g.

In qt4.py:

 from PyQt4.QtCore import *
 from PyQt4.QtGui import *

Then use it like this

 import qt4
 app = qt4.QApplication(...)
xioxox
  • 2,526
  • 1
  • 22
  • 22
  • 3
    Isn't this equivalent to "import PyQt4.QtCore as qt4"? I guess you'd need separate namespaces for QtCore and QtGui if you did that, but that doesn't seem like such a bad thing. – Colin Feb 25 '13 at 20:03
  • It's equivalent, if there's only one import in qt4.py. I've not found the distinction between the QtCore, QtGui, etc... very useful when programming. – xioxox Feb 26 '13 at 16:19
  • This is a nice solution that gets around the cruft at the top of source files. The Qt modules do not conflict with one another, so this introduces no problems as far as I can tell. – mfitzp Feb 22 '14 at 18:10
1

import for PyQt4 is a special case.
sometimes I'll choose the "first option" for quick and dirty coding, and turn it to the "second option" when the code grows longer and longer.
namespace collision maybe not a big deal here, I haven't see other package'name starts with a big "Q". and whenever I finish a PyQt4 script. convert"from PyQt4.QtGui import *" to sth. like "

from PyQt4.QtGui import (QApplication, QDialog, QLineEdit, QTextBrowser,
                         QVBoxLayout)

" just FYI, parentheses for multi-line import is handy here.

sunqiang
  • 6,422
  • 1
  • 32
  • 32
0

I am too absolutely against import * in the general case. In the case of PySide2, one of the rare exceptions applies:

from PySide2 import *

is the pattern to import all known modules from PySide2. This import is very convenient, because the import is always correct. The constant is computed from the CMAKE generator. Very helpful when quickly trying something in the interactive console, but also in automated testing.

For advanced usage, it makes also sense to use the PySide2.__all__ variable directly, which implements this feature. The elements of PySide2.__all__ are ordered by dependency, so first comes QtCore, then QtGui, QtWidgets, ... and so on.

Christian Tismer
  • 1,305
  • 14
  • 16