我想知道代码片段
之间是否有任何区别from urllib import request
和片段
import urllib.request
或者它们是否可以互换。如果它们是可互换的,这是“标准”/“首选”语法(如果有的话)?
谢谢!
答案 0 :(得分:196)
这取决于您在引用时如何访问导入。
from urllib import request
# access request directly.
mine = request()
import urllib.request
# used as urllib.request
mine = urllib.request()
为了简单起见,您也可以在导入时自行别名,或者避免屏蔽内置插件:
from os import open as open_
# lets you use os.open without destroying the
# built in open() which returns file handles.
答案 1 :(得分:144)
很多人已经解释过import
vs from
,所以我想尝试更多地解释一下实际差异所在。
首先,让我解释一下基本导入语句的确切内容。
import X
导入模块
X
,并在中创建对该模块的引用 当前命名空间然后,您需要定义完成的模块路径 从模块内部访问特定属性或方法(例如:X.name
或X.attribute
)
from X import *
导入模块
X
,并创建对所有公共对象的引用 由当前命名空间中的该模块定义(即一切 没有以_
开头的名称或任何名称 你提到过。或者换句话说,在你运行这个陈述之后,你可以简单地说 使用普通(非限定)名称来引用模块
X
中定义的内容。 但X
本身未定义,因此X.name
不起作用。如果name
已经定义,它被新版本取代。如果X
中的名字是 更改为指向其他对象,您的模块将不会注意到。这使得模块中的所有名称都可以在本地命名空间中使用。
现在让我们看看当我们import X.Y
时会发生什么:
>>> import sys
>>> import os.path
使用名称sys.modules
和os
检查os.path
:
>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
检查名为globals()
和locals()
的{{1}}和os
命名空间字典:
os.path
从上面的例子中,我们发现只有 >>> globals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> locals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> globals()['os.path']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'os.path'
>>>
被添加到本地和全局命名空间。
因此,我们应该可以使用os
:
os
...但不是 >>> os
<module 'os' from
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> os.path
<module 'posixpath' from
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>>
:
path
从>>> path
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined
>>>
命名空间中删除os
后,您将无法访问locals()
或os
,即使它们确实存在于os.path
中}}:
sys.modules
现在让我们看一下>>> del locals()['os']
>>> os
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>> os.path
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>
。
from
from
使用名称>>> import sys
>>> from os import path
和sys.modules
检查os
:
os.path
所以>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
看起来与我们使用sys.modules
导入时的情况相同。
好。我们来看看import name
和locals()
命名空间字符串的含义:
globals()
您可以使用>>> globals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> locals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['os']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'os'
>>>
进行访问,但不能使用path
:
os.path
让我们从locals()中删除'path':
>>> path
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> os.path
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>
使用别名的最后一个例子:
>>> del locals()['path']
>>> path
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined
>>>
没有定义路径:
>>> from os import path as HELL_BOY
>>> locals()['HELL_BOY']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['HELL_BOY']
<module 'posixpath' from /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>>
>>> globals()['path']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'path'
>>>
从两个不同的模块导入相同的from
时:
name
再次从>>> import sys
>>> from os import stat
>>> locals()['stat']
<built-in function stat>
>>>
>>> stat
<built-in function stat>
导入统计信息:
shutil
最后的进口将赢得
答案 2 :(得分:30)
功能上几乎没有什么区别,但第一种形式是优惠,正如你所做的那样
from urllib import request, parse, error
其中第二种形式必须是
import urllib.request, urllib.parse, urllib.error
并且你必须使用完全限定的名称来引用,这不太优雅。
答案 3 :(得分:17)
有区别。在某些情况下,其中一个将起作用,另一个则不起作用。这是一个例子:说我们有以下结构:
foo.py
mylib\
a.py
b.py
现在,我想将b.py
导入a.py
。我想将a.py
导入foo
。我该怎么做呢?我写的a
中的两个陈述:
import b
在foo.py
我写道:
import mylib.a
嗯,这会在尝试运行ImportError
时生成foo.py
。解释器会抱怨a.py
(import b
)中的import语句没有模块b。那怎么能解决这个问题呢?在这种情况下,将a
中的import语句更改为import mylib.b
由于a
和b
都在mylib
,因此无效。这里的解决方案(或至少一个解决方案)是使用绝对导入:
from mylib import b
答案 4 :(得分:3)
你正在使用Python3包中的urllib。这两种形式都是可以接受的,没有一种形式的进口优先于另一种形式。有时,当涉及多个包目录时,您可以使用前一个from x.y.z.a import s
在urllib包的这种特殊情况下,第二种方式import urllib.request
和urllib.request
的使用是标准库统一使用它的方式。
答案 5 :(得分:1)
在python 2.x中,至少你不能做import urllib2.urlopen
你必须from urllib2 import urlopen
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import urllib2.urlopen
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named urlopen
>>> import urllib.request
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named request
>>>
答案 6 :(得分:0)
我对import urllib.request的主要抱怨是你仍然可以引用urllib.parse,即使它没有被导入。
>>> import urllib3.request
>>> urllib3.logging
<module 'logging' from '/usr/lib/python2.7/logging/__init__.pyc'>
还请求我在urllib3下。 Python 2.7.4 ubuntu