【问题标题】:In python, what are the pros and cons of importing a class vs. importing the class's module?在 python 中,导入类与导入类的模块的优缺点是什么?
【发布时间】:2013-04-10 21:59:04
【问题描述】:

我正在为大约 30 名开发人员的团队编写一套 Python 编码指南。作为我的文档的基础,到目前为止,我已经研究了 Google python style guidePEP 8 style guide,并结合了两者的信息。

Google 样式指南比 PEP 8 更严格的一个地方是导入。 Google 指南要求开发人员仅导入包和模块,然后通过更合格的名称引用其中的项目。例如:

from pkg import module
...
my_class = module.MyClass()

理由是“每个标识符的来源都以一致的方式指示”。对于我们的项目,我们打算用两到三层深度的包来组织,所以要知道标识符的完整来源,读者可能无论如何都需要检查导入语句。我想提倡这种导入风格作为“首选风格”:

from pkg.module import MyClass
...
my_class = MyClass()

恕我直言,当名称更简洁时,列表推导等 Python 结构的可读性会得到提高。

我不清楚的是 python 解释器可能在幕后做什么。例如,MyClass 现在是这个模块和这个模块的所有导入器的全局命名空间的一部分吗? (这会很糟糕,可能会导致一些奇怪的错误;如果这是真的,我会提倡 Google 风格)。

我的python开发经验被限制在6个月左右(而且我们项目上没有太多专家可以咨询),所以我想从社区获得更多信息。以下是我已经研究过的一些项目:

effbot - discussion on imports

stack overflow - import vs. from import

python documentation - modules

python documentation - import

感谢您的回复!

【问题讨论】:

  • Anything 你可以直接引用的都是你模块中的全局变量。 MyClass 在你的第二个例子中确实是一个全局变量,在第一个例子中,module 是。
  • 我喜欢import blahvlah = blah.vlah。因为整个模块blah 无论如何都会被处理,即使我做了from blah import vlah
  • 除了 Martijn 回答的全球性问题之外,您是否还在寻找其他东西。如果是这样,你能把问题说得更清楚吗?
  • 在知名的Python项目中,比如Django或者fabric,可以看到from pkg.module import MyClass是最常用的样式。

标签: python import


【解决方案1】:

在 Python 中,不存在跨多个模块的全局变量。如果您执行from pkg.module import MyClass,则MyClass 位于您执行此操作的模块的全局命名空间中,但不在任何其他模块(包括导入导入 MyClass 的模块的模块)的全局命名空间中。

至于您的更一般的问题,视情况而定,任何一种导入机制都可以接受。如果模块名称很长,您可以通过以不同的名称导入它来缩短:

# Awkward
from package import reallylongmodule
reallylongmodule.MyClass()

# Less awkward
from package import reallylongmodule as rlm
rlm.MyClass()

如果类名足够独特,您可以知道它来自哪里以及它是什么,那么只导入类是可以的。但是,如果您有多个模块定义了具有相对难以描述的名称的类(例如,“处理器”、“单元”、“数据”、“管理器”),那么最好通过模块名称访问它们以澄清你在做什么。

风格指南最终是指南,而不是法律。我自己的偏好是选择一种能够最大限度地提高清晰度和可读性的机制。这涉及在避免冗长和繁琐的名称与避免简短、模糊或神秘的名称之间进行权衡。如何进行权衡取决于您正在使用的特定库以及如何使用它们(例如,您导入了多少模块,从它们导入了多少东西)。

【讨论】:

  • 同意!我认为任何一种风格都可以;只是更担心直接导入类(或函数)会产生微妙的影响。
【解决方案2】:

我建议您使用自动代码检查器,例如 pylint、pep8、pyflakes,而不是编写代码指南。

我个人更喜欢使用from pkg import module,因为可能会发生名称冲突。

from package import module

def my_fun():
   module.function()

Inpreter 必须执行 3 次哈希表查找本地函数命名空间、当前模块的全局命名空间和导入模块的命名空间。 在

from package.module import function

def my_fun():
   function()

它只会进行 2 次查找:最后一次是在导入时执行的。

【讨论】:

  • 我同意使用自动代码检查器;拥有文件的要求来自我们的客户。不过,我可能会将其作为指导项目!
猜你喜欢
  • 2021-08-06
  • 2011-10-15
  • 2020-07-23
  • 2022-12-09
  • 2015-10-06
  • 1970-01-01
  • 2015-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多