【问题标题】:In Python, is it a good practice to import all attributes with a wildcard?在 Python 中,使用通配符导入所有属性是一种好习惯吗?
【发布时间】:2013-01-31 22:03:14
【问题描述】:

为什么?

有时我需要导入模块的所有属性,因此我使用通配符导入,但我的一个 Vim 脚本(使用 flake8 作为其语法检查器)总是给我一个警告并告诉我无法检测到未定义的名称。

使用通配符导入还有其他缺点吗?

【问题讨论】:

    标签: python


    【解决方案1】:

    使用from module import * 通常不是一个好主意。通配符导入导致命名空间污染;您导入的名称比您需要的多,如果您不小心引用了导入的名称,您可能不会得到您想要的 NameError。

    此外,如果库的未来版本添加了其他名称,您最终可能会屏蔽其他名称,这仍然会导致奇怪的错误:

    from foo import bar
    from spam import *
    

    如果您升级 spam 并且它现在包含 spam.bar,它将替换上面一行中的 foo.bar 导入。

    【讨论】:

    • 命名空间污染绝对是最好的答案!
    【解决方案2】:

    使用通配符导入可能会导致细微的错误:

    foo.py

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

    python 控制台

    >>> 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'
    

    这在更新库版本时尤其重要。他们可能会也可能不会添加新变量并以可怕的方式破坏您的代码。

    如果您真的想使用 * 导入,请始终将其放在首位,以便其他导入和定义优先。

    【讨论】:

      【解决方案3】:

      到目前为止答案很好,但总是很高兴参考PyDocs

      虽然某些模块设计为在您使用 import * 时仅导出遵循特定模式的名称,但在生产代码中仍被认为是不好的做法。

      【讨论】:

      • 不幸的是,这句话并没有告诉你为什么这是一个不好的做法。
      【解决方案4】:

      answer by Martijn 正确解决了命名空间污染的问题,但我认为这里的任何答案都没有正确解决我认为最大的问题......这不是明确的.

      考虑一个假设的模块:

      #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)
      

      现在几个月后,你似乎不记得corn_beef_hash实际上是什么做了所以你去看看文档——除了你不记得corn_beef_hash是否是barbazqux 的一部分。这使得追踪变得更加困难。此外,如果您知道函数最初是在哪里定义的,那么这会给您一些关于它应该做什么的提示,这可以使代码更易于阅读。

      【讨论】:

        【解决方案5】:

        是的,如果您使用通配符导入所有内容,则从该包中获取所有内容并将其转换为脚本中的实例,这样做的更好方法是简单地导入包:

        例如。 导入包

        package.x
        

        这样您就不会遇到命名问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-09-09
          • 1970-01-01
          • 2021-01-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-06-23
          相关资源
          最近更新 更多