我试图找到一个综合指南,以了解最好是使用import module
仍是from module import
? 我刚开始使用Python,而且正在尝试着眼于最佳实践。 html
基本上,我但愿有人能分享他们的经验,其余开发人员有什么喜爱,以及避免未来遇到麻烦的最佳方法是什么? python
我刚刚发现了这两种方法之间的另外一个细微差异。 app
若是模块foo
使用如下导入: python2.7
from itertools import count
而后,模块bar
可能会错误地使用count
就像它是在foo
中定义的同样,而不是在itertools
定义的: ide
import foo foo.count()
若是foo
使用: 函数
import itertools
该错误仍然可能,但不太可能发生。 bar
须要: 测试
import foo foo.itertools.count()
这给我带来了麻烦。 我有一个模块,该模块错误地从一个未定义异常的模块中导入了一个异常,仅从其余模块中导入了该异常( from module import SomeException
)。 当再也不须要导入并将其删除时,有问题的模块将被破坏。 spa
这里还有另外一个细节,未说起,与写入模块有关。 固然,这可能不是很常见,可是我不时须要它。 code
因为引用和名称绑定在Python中的工做方式,若是您想从模块外部更新模块中的某些符号(例如foo.bar),并更改其余导入代码“ see”,则必须导入foo某种方式。 例如: htm
模块foo:
bar = "apples"
模块a:
import foo foo.bar = "oranges" # update bar inside foo module object
模块b:
import foo print foo.bar # if executed after a's "foo.bar" assignment, will print "oranges"
可是,若是导入符号名称而不是模块名称,则将没法使用。
例如,若是我在模块a中这样作:
from foo import bar bar = "oranges"
a以外的任何代码都不会将bar视为“橙色”,由于我对bar的设置仅影响模块a中的名称“ bar”,它没有“进入” foo模块对象并更新其“ bar”。
这是另外一个未说起的区别。 这是从http://docs.python.org/2/tutorial/modules.html逐字复制的
请注意,使用时
from package import item
该项目能够是包的子模块(或子包),也能够是包中定义的其余名称,例如函数,类或变量。 import语句首先测试项目是否在包装中定义; 若是不是,则假定它是一个模块并尝试加载它。 若是找不到它,则会引起ImportError异常。
相反,当使用相似
import item.subitem.subsubitem
除最后一个项目外,每一个项目都必须是一个包装; 最后一项能够是模块或包,但不能是上一项中定义的类或函数或变量。
即便许多人已经解释了import
import from
,我仍是想尝试多解释一下幕后发生的事情以及它发生的全部变化。
import foo
: 导入foo
,并在当前名称空间中建立对该模块的引用。 而后,您须要定义完整的模块路径,以从模块内部访问特定的属性或方法。
例如foo.bar
但不是bar
from foo import bar
: 导入foo
,并建立对列出的全部成员的引用( bar
)。 不设置变量foo
。
例如bar
但不是baz
或foo.baz
from foo import *
: 导入foo
,并建立对该模块在当前名称空间中定义的全部公共对象的引用(若是存在__all__
,则在__all__
列出的全部内容,不然全部不以_
开头的内容)。 不设置变量foo
。
例如bar
和baz
但不是_qux
或foo._qux
。
如今让咱们看看什么时候import XY
:
>>> 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 <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 >>>
import 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
发现了与以前相同的结果
OK,让咱们检查一下它在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' >>>
import package import module
使用import
,令牌必须是模块(包含Python命令的文件)或包( sys.path
包含文件__init__.py
的文件夹)。
有子包时:
import package1.package2.package import package1.package2.module
文件夹(包)或文件(模块)的要求相同,可是文件夹或文件必须在package2
内,而package2
必须在package1
,并且package1
和package2
必须包含__init__.py
文件。 https://docs.python.org/2/tutorial/modules.html
from
导入样式:
from package1.package2 import package from package1.package2 import module
程序包或模块输入包含import
语句的文件的名称空间做为module
(或package
)而不是package1.package2.module
。 您始终能够绑定到更方便的名称:
a = big_package_name.subpackage.even_longer_subpackage_name.function
只有from
导入样式容许您命名特定的函数或变量:
from package3.module import some_function
被容许,可是
import package3.module.some_function
不容许。