【问题标题】:Is there an accepted way to import all from the global namespace that is not "from module import *"是否有一种可接受的方式从全局命名空间中导入所有不是“从模块导入 *”
【发布时间】:2017-05-29 06:42:59
【问题描述】:

我有一个小应用程序,我想将它拆分成多个模块,以便我的代码结构更好,可读性更好。这样做的缺点是对于我导入的每个模块:

import module

然后我必须将 module.object 用于我想从该模块访问的任何对象。

在这种情况下,我不想污染全局命名空间,我想用正确的模块名称填充它,这样我就不必使用了

from module import *

为了调用一个没有模块前置的对象。

有没有一种方法可以做到这一点,而不是认为使用 from import 或 import 不好?

【问题讨论】:

  • from module import * 做的事情不好用。如果你可以用不同的语法做同样的事情,不管你怎么做,它仍然是不好用的。您必须在函数前面加上其模块或显式导入函数这一事实 是好的设计,也是您应该做的。
  • 所以,你想让你的代码“结构更好”,但你想直接引用符号而不用模块名???
  • 我同意,from module import * 本身就是一个快捷方式,符号应该以其模块开头。
  • 我不想污染命名空间,我想填充它”——我们都很难理解这种区别。您是说要导入 一些 模块符号,而不是 全部 个?
  • 谢谢文森特,我会接受并加前缀

标签: python python-2.7


【解决方案1】:

两个合理的选择是在导入前加上一个较短的名称。例如

import module as m
m.foo()

或显式导入您计划使用的名称:

from module import (foo,bar)
foo()

【讨论】:

    【解决方案2】:

    您应始终避免在导入时使用星号。所以要回答你的问题,我会说不,没有比这更好的方法了:

    import module
    
    module.method()
    

    import really_long_module_name as mm
    
    mm.method()
    

    在此处查看 pep8 指南“导入”部分: https://www.python.org/dev/peps/pep-0008/#imports

    应避免使用通配符导入( from import * ),因为它们使命名空间中存在哪些名称变得不清楚,从而使读者和许多自动化工具感到困惑。通配符导入有一个可辩护的用例,即重新发布一个内部接口作为公共 API 的一部分(例如,用可选加速器模块中的定义覆盖接口的纯 Python 实现,以及哪些定义将被被覆盖是事先不知道的)。

    Specific 比 globbing 更安全,我尽量只导入我需要的东西,如果我能提供帮助的话。当我学习一个新模块时,我会导入整个东西,然后一旦它处于良好状态,我就会返回并通过专门导入我需要的方法来重构:

    from module import method
    
    method()
    

    【讨论】:

      【解决方案3】:

      我不得不说您应该使用模块的名称。这是一种更好的使用方式,使您的代码没有命名空间混淆,而且非常易于理解。

      为了使您的代码更漂亮,您可以使用 as 导入:

      import random as r 
      # OR
      from random import randint as rint
      

      一个解决方案,我认为不是很漂亮,但是很有效,如果你不想污染全局命名空间,你可以尝试使用import 语句,例如函数内部。

      例如:

      >>> def a():
      ...     from random import randint
      ...     x = randint(0,2)
      ...     print x
      ...
      >>> a()
      1
      >>> randint(0,2)
      Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      NameError: name 'randint' is not defined
      

      这样,特定函数的本地命名空间被模块中的值填充,但全局命名空间是干净的。

      【讨论】:

      猜你喜欢
      • 2014-08-07
      • 2020-11-06
      • 2017-10-30
      • 1970-01-01
      • 2017-12-20
      • 2018-09-14
      • 2019-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多