打开终端, cd至my_package包所在的文件夹,但不要进入my_package。在这个文件夹下运行Python解释器。我使用的是IPython,因为它的自动补全功能非常方便:
- In [1]: import my_package
- In [2]: my_package.subpackage1.module_x
- Out[2]: <module 'my_package.subpackage1.module_x' from 'my_package/subpackage1/module_x.py'>
- In [3]: my_package.subpackage1.module_x.main
- spam spam spam
相对导入适用于你最终要放入包中的代码。如果你编写了很多相关性强的代码,那么应该采用这种导入方式。你会发现PyPI上有很多流行的包也是采用了相对导入。还要注意一点,如果你想要跨越多个文件层级进行导入,只需要使用多个句点即可。不过,PEP 328建议相对导入的层级不要超过两层。
还要注意一点,如果你往 module_x.py文件中添加了if__name__==‘__main__’,然后试图运行这个文件,你会碰到一个很难理解的错误。编辑一下文件,试试看吧!
- from . module_y import spam as ham
- def main:
- ham
- if __name__ == '__main__':
- # This won't work!
- main
现在从终端进入 subpackage1文件夹,执行以下命令:
- python module_x.py
如果你使用的是Python 2,你应该会看到下面的错误信息:
- Traceback (most recent call last):
- File "module_x.py", line 1, in <module>
- from . module_y import spam as ham
- ValueError: Attempted relative import in non-package
如果你使用的是Python 3,错误信息大概是这样的:
- Traceback (most recent call last):
- File "module_x.py", line 1, in <module>
- from . module_y import spam as ham
- SystemError: Parent module '' not loaded, cannot perform relative import
这指的是, module_x.py是某个包中的一个模块,而你试图以脚本模式执行,但是这种模式不支持相对导入。
如果你想在自己的代码中使用这个模块,那么你必须将其添加至Python的导入检索路径(import search path)。最简单的做法如下:
- import sys
- sys.path.append('/path/to/folder/containing/my_package')
- import my_package
注意,你需要添加的是 my_package的上一层文件夹路径,而不是my_package本身。原因是my_package就是我们想要使用的包,所以如果你添加它的路径,那么将无法使用这个包。
我们接下来谈谈可选导入。
可选导入(Optional imports)
如果你希望优先使用某个模块或包,但是同时也想在没有这个模块或包的情况下有备选,你就可以使用可选导入这种方式。这样做可以导入支持某个软件的多种版本或者实现性能提升。以github2包中的代码为例:
- try:
- # For Python 3
- from http.client import responses
- except ImportError: # For Python 2.5-2.7
- try:
- from httplib import responses # NOQA
- except ImportError: # For Python 2.4
- from BaseHTTPServer import BaseHTTPRequestHandler as _BHRH
- responses = dict([(k, v[0]) for k, v in _BHRH.responses.items])
lxml包也有使用可选导入方式:
- try:
- from urlparse import urljoin
- from urllib2 import urlopen
- except ImportError:
- # Python 3
- from urllib.parse import urljoin
- from urllib.request import urlopen
正如以上示例所示,可选导入的使用很常见,是一个值得掌握的技巧。
局部导入
当你在局部作用域中导入模块时,你执行的就是局部导入。如果你在Python脚本文件的顶部导入一个模块,那么你就是在将该模块导入至全局作用域,这意味着之后的任何函数或方法都可能访问该模块。例如:
- import sys # global scope
- def square_root(a):
- # This import is into the square_root functions local scope
- import math
- return math.sqrt(a)
- def my_pow(base_num, power):
- return math.pow(base_num, power)
- if __name__ == '__main__':
- print(square_root(49))
- print(my_pow(2, 3))
(编辑:威海站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|