很多人已经解释了import 与from,所以我想尝试在幕后解释更多,真正的区别在哪里。
首先,让我解释一下基本的 import 语句的作用。
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() 命名空间字典,名称为 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
>>>
从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
检查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:
>>> 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() 中删除“路径”:
>>> 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 导入统计数据:
>>>
>>> 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'>
>>>
最后的导入将获胜