【问题标题】:From-Import while retaining access by moduleFrom-Import 同时保留按模块访问
【发布时间】:2013-08-18 14:28:25
【问题描述】:

标题有点难懂,但我的问题很简单。

我有一个程序需要从 sqrt() 获取某些东西,但这是我唯一需要来自 math 的东西。导入整个模块来获取单个函数似乎有点浪费。

我可以说from math import sqrt,但随后sqrt() 将被添加到我的程序的主命名空间中,我不希望这样(特别是因为我计划将程序更改为可用作模块;会像那样导入在那种情况下会导致问题吗?)。有没有什么方法可以只导入那个函数,同时仍然保留math.sqrt() 语法?

在这种特定情况下,我使用的是 Python 2.7,但如果 Python 3 有不同的答案,我也想听听以供将来参考。

【问题讨论】:

    标签: python python-2.7 code-readability


    【解决方案1】:

    无论哪种方式,您都可以“导入”完整的math 模块,因为它已编译并存储在sys.modules 中。因此,与import math 相比,如果您执行from math import sqrt,则您没有任何优化优势。他们做同样的事情。他们导入整个 math 模块,将其存储在 sys.modules 中,然后唯一的区别是第一个将 sqrt 函数带入您的命名空间,第二个将 math 模块带入您的命名空间。但是这些名称只是引用,因此仅从模块中导入一件事不会在内存方面或 CPU 方面受益。

    如果您想要math.sqrt 语法,那么只需使用import math。如果您想要sqrt() 语法,请使用from math import sqrt

    如果您担心模块的用户在进行星号导入时不会污染他的命名空间:from your_module import * 然后在您的模块中定义一个 __all__ 变量,该变量是表示将在以下情况下导入的对象的字符串列表您的模块的用户开始导入。

    【讨论】:

    • 啊,我不知道。有用的信息。可以肯定的是,py2exe 是否会以任何方式改变这种情况?
    • 不,py2exe 不会改变 python 导入模块的方式。
    【解决方案2】:

    math import sqrt 使用。您可以使用__all__ 语句保护从模块中导出的函数。 __all__ 应该是您要从模块中导出的名称列表。

    【讨论】:

    • __all__ 只影响from ... import *,无论如何都不应该使用它。
    • 是的,但他想将他的程序作为一个模块提供给其他人使用。那么__all__ 是一个更好的方法,至少比免责声明更可取:“使用此模块时不要使用import *”。
    • 可能有用,但不要使用-import * 规则不应该出现在模块的文档中,它应该出现在风格指南和人民中头。更重要的是,如果按照应使用的方式使用模块,即使用 import modulefrom module import specific_thing,您提出的解决方案将无济于事。再说一次,我什至不确定是否有问题。
    • 确实,如果 OP 的用户按照您建议的方式仅使用 import OP 的模块,则名称空间污染没有问题。我的建议是针对 OP 的用户不按照您建议的方式使用 import 的情况。
    • 我明白这一点。我的部分观点是恕我直言,这种方式 (import *) 不是一个应该担心支持良好的用例,因为它通常不被鼓励(参见每个样式指南)并且还有许多其他问题。
    【解决方案3】:

    简短的回答是否定的。只需执行from math import sqrt。将脚本作为模块使用不会造成任何问题,也不会降低代码的可读性。

    【讨论】:

      【解决方案4】:

      不,这是不可能的,因为模块是如何工作的。 import math 怎么了?

      考虑:

      module.py

      x = 1
      
      def foo():
          return x
      
      x = 2
      
      def bar():
          returnx
      

      主要(伪代码):

      import main but_only foo
      
      print foo()
      

      直到遇到def foo 行,Python 才知道 foo 函数。您提议的是从模块中随机选择行。但是python怎么知道哪几行呢?在这个例子中,foo() 会返回什么值?

      【讨论】:

        猜你喜欢
        • 2014-04-10
        • 1970-01-01
        • 1970-01-01
        • 2012-06-05
        • 2021-12-23
        • 2012-11-07
        • 2021-11-11
        相关资源
        最近更新 更多