from ... import OR import ... 对于模块

Posted

技术标签:

【中文标题】from ... import OR import ... 对于模块【英文标题】:from ... import OR import ... as for modules 【发布时间】:2020-10-02 23:36:07 【问题描述】:

我应该使用

from foo import bar

import foo.bar as bar

导入模块并且不需要/希望更改名称 (bar)?

有什么不同吗?有关系吗?

【问题讨论】:

尽量避免as 为什么?它在这里看起来是多余的,但在 Python 世界中,需要导入与其他东西同名的东西是很常见的。即使没有必要,也有常见的风格原因,例如import pandas as pdimport numpy as np,在处理这些项目时非常标准——这是我随处可见的代码,也是文档中建议的导入。我真的不认为使用as 有什么问题,它通常可以使代码更易于阅读。 【参考方案1】:

两者在技术上是不同的:

import torch.nn as nn导入一个模块/包torch.nn,其中 from torch import nn 可以并且更愿意从torch 模块/包中导入属性.nn。导入一个模块/包torch.nn 是一个fall.back。

在实践中,使用相同的完全限定名称来指代两个不同的事物是不好的风格。因此,torch.nn 应该只引用一个模块/包。在这种常见情况下,两个 import 语句在功能上是等效的:导入同一个对象并绑定到同一个名称。

如果目标始终是模块,则选择哪一个取决于偏好。重构时存在实际差异:

import torch.nn as nn 保证 .nn 是一个模块/包。它可以防止意外使用属性产生阴影。 from torch import nn 不在乎 .nn 是什么。它允许透明地更改实现。

7.11. The import statement

基本的导入语句(没有from子句)分两步执行:

    找到一个模块,必要时加载并初始化它 在本地命名空间中为 import 语句出现的范围。

[...]

from 表单使用稍微复杂一点的过程:

    找到from子句中指定的模块,必要时加载并初始化它;

    对于导入子句中指定的每个标识符:

      检查导入的模块是否具有该名称的属性 如果不是,尝试导入具有该名称的子模块,然后再次检查导入的模块的该属性

【讨论】:

【参考方案2】:

import modulefrom module import 之间的区别主要是主观的。选择您最喜欢的一个,并在使用时保持一致。以下是两者的一些优势,可帮助您做出决定。

进口优势

    减少对导入语句的维护。 无需添加任何额外的导入即可开始使用模块中的其他项

from torch import nn 的优势

    使用 nn 输入更少 对可以访问模块的哪些项目进行更多控制

【讨论】:

【参考方案3】:

假设barfoo中的模块或包,没有区别*,没关系。这两个语句的结果完全相同:

>>> import os.path as path
>>> path
<module 'posixpath' from '/Users/mj/Development/venvs/***-2.7/lib/python2.7/posixpath.pyc'>
>>> from os import path
>>> path
<module 'posixpath' from '/Users/mj/Development/venvs/***-2.7/lib/python2.7/posixpath.pyc'>

如果bar不是模块或包,则第二种形式不起作用;而是抛出回溯:

>>> import os.walk as walk
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named walk

* 在 Python 3.6 及之前的版本中,包含其他模块的包的初始化顺序存在一个错误,其中 在包的加载阶段使用import contained.module.something as aliasfrom contained.module import something as alias 不会失败的子模块中。请参阅 Imports in __init__.py and `import as` statement 以获得该问题的一个非常说明性的示例,以及 Python 问题 #23203 和 #30024。

【讨论】:

嗨@Martijn Pieters :),有什么理由使用import os.path as path 风格吗?不是这个例子..我的意思是我已经在 github、CPython、Django 等上搜索了一些最大的项目......import x 类型的绝对导入是简单的,只有 1 个单词,不会强制使用别名做import x.y.z as my_z。我的意思是如果没有别名,导入是没有用的;如果您执行import x.y.z,它只导入x 并将其绑定到当前命名空间中,为了使用z,您必须始终执行x.y.z,每次 @George:大多数开发者会使用from x.y import z,问题中使用的语法并不常见。 对,我的想法完全正确......我遵循谷歌的约定只导入包和模块(因为 PEP8 没有强制执行此操作,但无论 PEP8 不完整,我都会通过谷歌执行它以支持任何其他大型项目,如 Reddit、OpenStack 等......仅仅因为谷歌......好吧......谷歌 :) 并且在导入包和模块时,我使用你上面所说的......import x 只是一个普通的module/package 并访问 attrs thorugh x (在大模块中不言自明),无论我必须深入超过 1 级,我都会使用 from x.y import z;谢谢回复:) 是的,我看到了。将python版本的问题添加到答案中会很好! @beesleep:我为此添加了一个脚注。【参考方案4】:

这是一个较晚的答案,来自what is the difference between 'import a.b as b' and 'from a import b' in python

此问题已被标记为重复问题,但其他机制尚未解决这两种机制之间的重要区别。

from foo import bar 将名为 bar任何 对象从命名空间 foo 导入当前命名空间。

import foo.bar as bar 导入一个名为 foo.bar 的可导入对象(包/模块/命名空间),并为其赋予别名 bar

有什么区别?

获取一个名为foo 的目录(包),其中有一个__init__.py,其中包含:

# foo.__init__.py
class myclass:
    def __init__(self, var):
        self.__var = var

    def __str__(self):
        return str(self.__var)

bar = myclass(42)

同时,foo 中还有一个模块,名为bar.py

from foo import bar
print(bar)

给予:

42

鉴于:

import  foo.bar as bar
print(bar)

给予:

<module 'foo.bar' from '/Users//..../foo/bar.py'>

所以可以看出import foo.bar as bar更安全。

【讨论】:

我不同意这一点。 __init__.py 文件是模块与外界的接口。如果__init__ 文件导致导入发生更改,那很可能是作者的意图。使用标准方式导入模块更安全。 PEP8 推荐 from x import y 样式。 python.org/dev/peps/pep-0008/#imports 问题是,有区别吗?有,而且可能会产生意想不到的副作用。 我不同意import ... as 更安全的评论,而不是您的其他答案。它可能有“副作用”,但它们可能是模块作者的意图。绕过模块的预期接口会破坏抽象并自找麻烦。 from foo import bar 似乎更“安全”,从提供的证据来看。【参考方案5】:

您可以使用 as 重命名模块,假设您有两个具有视图的应用程序并且您想要导入它们

from app1 import views as views1
from app2 import views as views2

如果要多次导入,请使用逗号分隔

>>> from datetime import date as d, time as t
>>> d
<type 'datetime.date'>
>>> t
<type 'datetime.time'>

【讨论】:

【参考方案6】:

对于第二个选项,我唯一能看到的是,您需要的行数与要导入的内容一样多。例如 :

import foo.bar as bar
import foo.tar as tar
import foo.zar as zar

而不是简单地做:

from foo import bar, tar, zar

【讨论】:

PEP8 建议将导入放在单独的行:python.org/dev/peps/pep-0008/#imports。 @RichSmith 关于您的链接,它实际上说在一行中从同一个包中导入多个东西是正确的(“虽然可以这么说”部分)。 我一直将这一行解释为 PEP8 表示可以从一行中的单个模块导入类和常量等(subprocess 是一个模块)。它可以解释为“这种风格还可以”,但上面写着Imports should usually be on separate lines。可能会更清楚。 我问过这个问题:***.com/questions/62087225/…

以上是关于from ... import OR import ... 对于模块的主要内容,如果未能解决你的问题,请参考以下文章

`from ... import`与`import .` [重复]

Python的from import和import的区别

浅谈python中得import xxx,from xxx import xxx, from xxx import *

import 和from ...import

Python中import, from...import,import...as的区别

python中import 和from import的区别