In Python, is it a good practice to import all attributes with a wildcard?

前端 未结 5 1649
清歌不尽
清歌不尽 2020-12-21 06:48

and why?

Sometimes I need import all the attributes of a module so I use wildcard importing, but one of my Vim scripts(using flake8 as its syntax checker) always giv

相关标签:
5条回答
  • 2020-12-21 06:52

    It's generally not a good idea to use from module import *. Wildcard importing leads to namespace pollution; you imported more names than you need and if you accidentally refer to an imported name you may not get the NameError you wanted.

    Also, if a future version of the library added additional names, you could end up masking other names, leading to stranger bugs still:

    from foo import bar
    from spam import *
    

    If you upgrade spam and it now includes a spam.bar it'll replace the foo.bar import in the line above.

    0 讨论(0)
  • 2020-12-21 07:00

    Using the wildcard import can cause subtle bugs:

    foo.py

    import sys
    os = sys # just for the fun of it... :-D
    

    python console

    >>> import os
    >>> from foo import *
    >>> os.path.join('p1', 'p2')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'list' object has no attribute 'join'
    

    This is especially important when updating library versions. They might or might not add new variables and break your code in horrible ways.

    If you really want to use the * import always place it first so that other imports and definitions take precedence.

    0 讨论(0)
  • 2020-12-21 07:00

    Good answers so far, but always nice to refer to the PyDocs:

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

    0 讨论(0)
  • 2020-12-21 07:02

    The answer by Martijn correctly addresses the issue of namespace polution, but I don't think any of the answers here have yet correctly addressed what I consider to be the biggest problem ... It's not explicit.

    Consider a hypothetical module:

    #foo.py
    from bar import *
    from baz import *
    from qux import *
    
    def breakfast(x):
        with corn_beef_hash(x) as yummy:
            for egg in yummy:
                yield ham(egg.scrambled)
    

    Now a few months later, you can't seem to remember what corn_beef_hash actually does so you go to look at the documentation -- except that you can't remember whether corn_beef_hash was part of bar or baz or qux. This makes it harder to track down. Also, if you know where the function was originally defined, that gives you some hints about what it's supposed to be doing which can make the code easier to read.

    0 讨论(0)
  • 2020-12-21 07:03

    Yes there are, if you import everything using the wildcard you take everything from that package and turn it into an instance in your script, a better way of doing this is to simply import the package:

    ex. import package

    package.x
    

    this way you won't run into naming issues.

    0 讨论(0)
提交回复
热议问题