如果你使用的是Python 2,你应该会看到下面的错误信息:
Traceback (most recent call last):
File "module_x.py", line 1, in module
from . module_y import spam as hamValueError: 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 hamSystemError: Parent module '' not loaded, cannot perform relative import
这指的是,module_x.py 是某个包中的一个模块,而你试图以脚本模式执行,但是 这种模式不支持相对导入。
如果你想在自己的代码中使用这个模块,那么你必须将其添加至Python的导入检索路径(import search path) 。最简单的做法如下:
import syssys.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 responsesexcept 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 urlopenexcept 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))
这里,我们将 sys 模块导入至全局作用域,但我们并没有使用这个模块 。然后,在 square_root 函数中 , 我们将 math
模块导入至该函数的局部作用域,这意味着 math 模块只能在 square_root 函数内部使用 。如果我们试图在 my_pow 函数中使用
math,会引发 NameError。试着执行这个脚本 , 看看会发生什么 。
使用局部作用域的好处之一,是你使用的模块可能需要很长时间才能导入,如果是这样的话,将其放在某个不经常调用的函数中或许更加合理,而不是直接在全局作
用域中导入 。老实说,我几乎从没有使用过局部导入,主要是因为如果模块内部到处都有导入语句,会很难分辨出这样做的原因和用途 。
根据约定,所有的导入语句都应该位于模块的顶部。
导入注意事项
在导入模块方面,有几个程序员常犯的错误 。这里我们介绍两个 。
循环导入(circular imports)
覆盖导入(Shadowed imports,暂时翻译为覆盖导入)
- 如何使用cmd命令行提示符登录mysql服务器 cmd中登陆mysql
- mysql怎么设置时区 mysql时间显示设置
- 招聘要精通mysql
- mysql 65535 8192 限制 mysql限制资源使用
- mysql有topn
- mysql协议包解析 mysqlicp协议
- mysql子查询和连接查询 mysql子查询插入
- Mysql使用索引查询 mysql使用round
- redis实现延时消息队列 redis消息时间过长
- redis的热点数据缓存 redis热点数据切换
