Python 导入机制对我来说始终是一个神话。有时导入包可以授予对其下面的模块的访问权限。例如,
import urllib
urllib.parse.unquote
gives
<function urllib.parse.unquote>
这表明即使仅导入包(即本例中的 urllib),也可以访问函数,但不能深入到模块文件。这是在 Jupyter Notebook 中完成的。
但是当我在终端做同样的事情时
>>> import urllib
>>> urllib.parse.unquote
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'urllib' has no attribute 'parse'
两个 Python 版本都是 3.6.1。
有什么区别以及什么是好的做法?
编辑以合并 @user2357112 和 @Tomoki 的答案。
直接来自@user2357112
要访问 urllib.parse 才能正常工作,必须满足以下两个条件:
The urllib
模块对象必须绑定到urllib
名称,无论是在本地、全局还是某个封闭范围内。
这urllib.parse
子模块必须已初始化并绑定到解析属性urllib
模块对象。
进口urllib
在当前本地或全局范围(或任何封闭范围)中满足第一个条件。
An import urllib.parse
在程序中的任何位置执行满足第二个条件,因为它加载子模块并将其绑定到parse
属性上的urllib
模块对象,并且只有一个urllib
整个程序的模块对象。
在以下环境中urllib.parse
简单导入后即可访问urllib
,必须加载一些其他代码urllib.parse
,让你看到它。
证据由@Tomoki提供
Test: "import IPython"
└─IPython:┐
┌────┘
├──"from core.application import Application"
│ └──IPython.core.application: "from IPython.core import release, crashhandler"
│ └──IPython.core.crashhandler: "from IPython.core import ultratb"
│ └──IPython.core.ultratb: "import pydoc"
│ └──pydoc: "import urllib.parse"
└──"from terminal.embed import embed"
└──IPython.terminal.embed:┐
┌───────────┘
├──"from IPython.core import magic_arguments"
│ └──IPython.core.magic_arguments: "from IPython.utils.text import dedent"
│ └──IPython.utils.text: "from pathlib import Path"
│ └──pathlib: "from urllib.parse import quote_from_bytes"
├──"from IPython.core.magic import Magics, magics_class, line_magic"
│ └──IPython.core.magic: "from IPython.core import oinspect"
│ └──IPython.core.oinspect: "from IPython.core import page"
│ └──IPython.core.page: "from IPython.core.display import display"
│ └──IPython.core.display: "import mimetypes"
│ └──mimetypes: "import urllib.parse"
└──"from IPython.terminal.interactiveshell import TerminalInteractiveShell"
└──pygments.plugin: "import pkg_resources"
└──pkg_resources: "import email.parser"
└──email.parser: "from email.feedparser import FeedParser, BytesFeedParser"
└──email.feedparser: "from email._policybase import compat32"
└──email._policybase: "from email.utils import _has_surrogates"
└──email.utils: "import urllib.parse"
最后一行确实触及urllib.parse
.
另一个证据
import scipy
不提供访问scipy.stats.norm
在终端或 Jupyter 笔记本中,因为没有任何环境接触scipy.stats
at all.
什么是好的做法?
从上面我们可以得出结论,这不仅是一个好的实践,而且实际上是##导入整个模块级别##的要求。
“始终导入到文件(模块)级别以保证访问”
谢谢大家的回答!