【问题标题】:'from X import a' versus 'import X; X.a''from X import a' 与 'import X; X.a'
【发布时间】:2008-10-09 09:04:34
【问题描述】:

我看到一些 Python 程序员相当一致地使用以下样式(我们将其称为样式 1):

import some_module
# Use some_module.some_identifier in various places.

为了支持这种风格,您可以引用"explicit is better than implicit" 格言。我见过其他程序员使用这种风格(风格 2):

from some_module import some_identifier
# Use some_identifier in various places.

我在样式 2 中看到的主要好处是可维护性——尤其是对于 duck typing 理想,我可能想将 some_module 换成 some_other_module。我也觉得风格 2 用"readability counts" 格言赢得积分。尽管我倾向于不同意,但人们总是会争辩说,在使用第一种样式时,搜索和替换同样是一个不错的选择。

附录: 注意到您可以使用as 来解决样式1 中从some_modulesome_other_module 的切换。我忘了提到,决定在你的 current 模块中实现some_identifier,这使得创建等效的some_module 容器有点尴尬。

【问题讨论】:

    标签: python python-import maintainability duck-typing


    【解决方案1】:

    这两种情况都有用,所以我不认为这是一个非此即彼的问题。 我会考虑在以下情况下使用模块 import x,y,z

    • 要导入的东西很少

    • 与模块名称分离时,导入函数的目的很明显。如果名称相当通用,它们可能会与其他名称发生冲突,并且几乎不会告诉您什么。例如。看到remove 告诉你的很少,但os.remove 可能会暗示你正在处理文件。

    • 名称不会冲突。与上述类似,但更重要。 从不做以下事情:

       from os import open
      

    import module [as renamed_module] 的优点是它提供了更多关于使用它时所调用内容的上下文。它的缺点是,当模块没有真正提供更多信息时,这会有点混乱,并且性能稍差(2 次查找而不是 1 次)。

    然而,它在测试时也有优势(例如,用模拟对象替换 os.open,而不必更改每个模块),并且应该在使用可变模块时使用,例如

    import config
    config.dburl = 'sqlite:///test.db'
    

    如果有疑问,我总是选择import module 风格。

    【讨论】:

      【解决方案2】:

      存在以下语法:

      import some_other_module as some_module
      

      风格 2 的可维护性论点不再相关。

      我倾向于使用样式 1。通常,我发现在典型的 Python 程序中我只显式引用导入的包名称几次。其他都是对象上的方法,当然不需要引用导入的包。

      【讨论】:

        【解决方案3】:

        我通常使用阈值来决定这一点。如果我想在some_module 中使用很多东西,我会使用:

        import some_module as sm
        x = sm.whatever
        

        如果我只需要一两件事:

        from some_module import whatever
        x = whatever
        

        当然,这是假设我不需要来自some_other_modulewhatever

        我倾向于在导入时使用as 子句,以便我可以减少输入在未来很容易替换另一个模块。

        【讨论】:

          【解决方案4】:

          我更喜欢import X,然后尽可能使用X.a

          我的异常集中在像 Django 这样的大框架中的深层嵌套模块上。他们的模块名称往往很长,他们的例子都说from django.conf import settings,以免你在任何地方输入django.conf.settings.DEBUG

          如果模块名称嵌套很深,则例外是使用from X.Y.Z import a

          【讨论】:

            【解决方案5】:

            我发现这个符号

            from some_module import some_symbol
            

            在大多数情况下效果最好。此外,如果符号名称冲突,您可以使用:

            from some_module import some_symbol as other_symbol
            

            正如问题所述,它避免了一直重写模块名称,每次都存在输入错误的风险。我使用语法:

            import  module [as other_module]
            

            仅在两种情况下:

            1. 我使用了太多的模块函数/对象来全部导入
            2. 模块定义了一些可能在执行过程中改变的符号

            【讨论】:

              【解决方案6】:

              我个人尽量不要把我的命名空间搞得太乱,所以在大多数情况下我只是这样做

              import module  
              

              或 导入模块作为模组

              唯一真正的区别是当我有一个带有一个经常使用的类的模块时。如果我对 list 类型进行子类化以在其中添加一些功能,我会使用

              from SuperImprovedListOverloadedWithFeatures import NewLIst
              nl = NewList()
              

              等等

              【讨论】:

                【解决方案7】:

                我倾向于只使用每个模块的几个成员,所以有很多

                from john import cleese
                from terry import jones, gilliam
                

                在我的代码中。如果我希望使用大部分模块并且模块名称很短,我将导入整个模块(例如oswx)。如果存在名称冲突或者我想提醒读者该函数与什么相关联,我也会导入整个模块。

                import michael
                import sarah
                
                import wave
                
                gov_speech = wave.open(sarah.palin.speechfile)
                parrot_sketch = wave.open(michael.palin.justresting)
                

                (我可以使用from wave import open as wave_open,但我认为wave.open 对读者来说会更熟悉。

                【讨论】:

                  【解决方案8】:
                  【解决方案9】:

                  我相信更新版本的 Python(2.5+?必须检查我的事实...)你甚至可以这样做:

                  import some_other_module as some_module
                  

                  因此,您仍然可以使用样式 1 并稍后换入不同的模块。

                  我认为它通常映射到您希望多少混乱您的命名空间。您会在模块中只使用一两个名称吗?还是全部(from x import * 并不总是很糟糕,只是一般而言)?

                  【讨论】:

                    猜你喜欢
                    • 2019-08-22
                    • 1970-01-01
                    • 2020-07-23
                    • 1970-01-01
                    • 2017-09-18
                    • 1970-01-01
                    • 2019-07-07
                    • 2017-07-24
                    • 2012-03-15
                    相关资源
                    最近更新 更多