from ... import或import ...对于模块

emb*_*ert 42 python import module

我应该用吗?

from foo import bar
Run Code Online (Sandbox Code Playgroud)

要么

import foo.bar as bar
Run Code Online (Sandbox Code Playgroud)

导入模块,并和有改变名字没有必要/愿望(bar)?

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

Mar*_*ers 37

假设这bar是一个模块或包foo,没有区别,没关系.这两个语句具有完全相同的结果:

>>> import os.path as path
>>> path
<module 'posixpath' from '/Users/mj/Development/venvs/stackoverflow-2.7/lib/python2.7/posixpath.pyc'>
>>> from os import path
>>> path
<module 'posixpath' from '/Users/mj/Development/venvs/stackoverflow-2.7/lib/python2.7/posixpath.pyc'>
Run Code Online (Sandbox Code Playgroud)

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

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

  • 嗨@Martijn Pieters :),是否有任何理由使用“import os.path as path”样式?不是特别是这个例子..我的意思是我已经搜索了 github、CPython、Django 等上的一些最大的项目...“import x”类型的绝对导入是简单的,只有 1 个单词,不强制使用别名通过执行“import xyz as my_z”。我的意思是,如果没有别名,导入就没用;如果你执行“import xyz”,它只会导入“x”并将其绑定在当前名称空间内,为了使用“z”,你必须每次都执行“xyz” (2认同)

Mis*_*agi 15

两者在技术上是不同的:

  • import torch.nn as nn导入一个模块/包torch.nn,何在
  • from torch import nn可以并且愿意.nntorch模块/包中导入一个属性。导入模块/包torch.nn是一种回退。

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

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

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

7.11. 进口声明

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

  1. 找到一个模块,必要时加载并初始化它
  2. 在本地命名空间中为发生import语句的范围定义一个或多个名称。

[...]

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

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

  2. 对于 import 子句中指定的每个标识符:

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


小智 13

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

from app1 import views as views1
from app2 import views as views2
Run Code Online (Sandbox Code Playgroud)

如果你想多次导入使用逗号分隔

>>> from datetime import date as d, time as t
>>> d
<type 'datetime.date'>
>>> t
<type 'datetime.time'>
Run Code Online (Sandbox Code Playgroud)


Dep*_*ado 11

我唯一能看到的第二个选项就是你需要输入与你要导入的东西一样多的行.例如 :

import foo.bar as bar
import foo.tar as tar
import foo.zar as zar
Run Code Online (Sandbox Code Playgroud)

而不是简单地做:

from foo import bar, tar, zar
Run Code Online (Sandbox Code Playgroud)


cda*_*rke 8

这是一个迟到的答案,源于python中'import ab as b'和'from a import b'之间的区别

这个问题被标记为重复,但两个机制之间存在重要差异,而其他机制尚未解决.

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)
Run Code Online (Sandbox Code Playgroud)

与此同时,有同样的模块中foobar.py.

from foo import bar
print(bar)
Run Code Online (Sandbox Code Playgroud)

得到:

42
Run Code Online (Sandbox Code Playgroud)

鉴于:

import  foo.bar as bar
print(bar)
Run Code Online (Sandbox Code Playgroud)

得到:

<module 'foo.bar' from '/Users//..../foo/bar.py'>
Run Code Online (Sandbox Code Playgroud)

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

  • 我不同意这一点。`__init__.py` 文件是模块与外界的接口。如果 `__init__` 文件导致导入被更改,这很可能就是作者的意图。使用标准方式导入模块更安全。PEP8 推荐“from x import y”样式。https://www.python.org/dev/peps/pep-0008/#imports (3认同)
  • 问题是,有区别吗?确实存在,而且可能会产生意想不到的副作用。 (2认同)
  • 我不同意“import ... as”更安全的评论,而不是你答案的其余部分。它可能有“副作用”,但它们可能是模块作者的意图。绕过模块的预期接口会破坏抽象并自找麻烦。 (2认同)