我想知道下面代码片段之间是否有区别:
from urllib import request
和片段
import urllib.request
或者它们是否可以互换使用?如果可以互换,哪种是“标准”/“首选”语法(如果有的话)?
我想知道下面代码片段之间是否有区别:
from urllib import request
和片段
import urllib.request
或者它们是否可以互换使用?如果可以互换,哪种是“标准”/“首选”语法(如果有的话)?
这取决于您希望在引用时如何访问该导入项。
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.
许多人已经解释了import
与from
的区别,因此我想尝试更深入地解释一下它们之间的实际区别。
首先,让我解释一下基本的导入语句都做了什么。
import X
导入模块
X
并在当前命名空间中创建对该模块的引用。然后需要定义完成的模块路径来从模块内部访问特定属性或方法(例如:X.name
或X.attribute
)。
from X import *
导入模块
X
并在当前命名空间中创建对该模块定义的所有公共对象的引用(即除了以_
开头的名称之外的所有内容)或者您指定的名称。换句话说,在运行此语句之后,您只需使用简单的(未经限定的)名称即可引用模块
X
中定义的内容。但是,并没有定义X
本身,所以X.name
不能工作。如果name
已经定义,则被新版本取代。如果X
中的name被更改以指向其他对象,则您的模块不会注意到。这使得模块中的所有名称都在本地命名空间中可用。
现在让我们看看当我们执行import X.Y
时会发生什么:
>>> import sys
>>> import os.path
检查名称为os
和os.path
的sys.modules
:
>>> 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'>
使用名称 os
和 os.path
检查 globals()
和 locals()
命名空间字典:
>>> 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
>>>
如果你从locals()
命名空间中删除了os
,那么即使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
检查名为 os
和 os.path
的 sys.modules
:
>>> 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
:
>>> 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
>>>
让我们从locals()中删除'path':
>>> 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
导入stat
:
>>>
>>> from shutil import stat
>>> locals()['stat']
<module 'stat' from
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/stat.pyc'>
>>> stat
<module 'stat' from
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/stat.pyc'>
>>>
最后导入的内容将会覆盖之前的同名内容
from . import <classyouwant>
是 Python 中的一种导入方式,它表示从当前模块中导入指定的类。其中的点 .
表示当前模块所在的包。 - Azurespot有所不同。在某些情况下,其中一个可能有效,而另一个则不行。以下是一个示例:假设我们有以下结构:
foo.py
mylib\
a.py
b.py
现在,我想将 b.py
导入到 a.py
中。同时,我希望将 a.py
导入到 foo
中。我应该如何做?在 a.py
中,我需要写两条语句:
import b
foo.py
中,我写道:import mylib.a
如果尝试运行foo.py
时,会生成一个ImportError
。解释器会抱怨a.py
文件中的导入语句(import b
),说没有b模块。那么如何修复这个问题呢?在这种情况下,将a
文件中的导入语句更改为import mylib.b
并不能解决问题,因为a
和b
都在mylib
中。解决方案(或至少一个解决方案)是使用绝对导入:
from mylib import b
您正在使用Python3中的urllib包。两种形式都可以接受,没有一种导入形式优于另一种。有时候,当涉及到多个包目录时,您可能需要使用前一种形式from x.y.z.a import s
。
在这种特定情况下,使用第二种方式import urllib.request
和使用urllib.request
是标准库统一使用的方式。
在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
>>>
urlopen
是一个函数,对吧?这就像试图导入os.chdir
一样——正如错误信息正确地指出的那样,“没有名为chdir
的模块”……因为它不是一个模块! - wchargin>>> import urllib3.request
>>> urllib3.logging
<module 'logging' from '/usr/lib/python2.7/logging/__init__.pyc'>
还有一个请求是关于urllib3的。Python 2.7.4 ubuntu。
sys.modules
зҡ„ж–№ејҸжңүжүҖдёҚеҗҢпјҡиҜ·зңӢдёҖдёӢиҝҷдёӘзӯ”жЎҲпјҲеңЁжң«е°ҫпјүгҖӮ*(д№ҹи®ёжңүдәәжҜ”жҲ‘жӣҙеҘҪең°и§ЈйҮҠ)* - Rik Poggi