未加星标

Python的包导入机制

字体大小 | |
[系统(linux) 所属分类 系统(linux) | 发布者 店小二04 | 时间 20161001 | 作者 红领巾 ] 0人收藏点击收藏

Background
python的大型项目中,一般都会用到模块包来组织文件层次,其中当一个目录内含有__init__ . py文件时,就可以視该目录为一个模块包。
当在模块包中使用import语句的时候,不同的语法会导致不同的模块搜索导入方式,常见的导入方式如下:
绝对导入(absolute import)
显式相对导入(explicit relative import)
隐式相对导入(implicit relative import)

需要注意的是,这些导入方式都是对于模块包而言,对于一般的模块还是从sys.path搜索入手。

Prerequisite

Python脚本运行的方式?

Python脚本运行分为两种方式:一种是作为top level script运行,另一种则是作为被导入的包模块运行。

当使用python命令直接执行一个py文件的时候,该文件就是以top level script方式运行,此时文件的__name__属性则为__main__。

# test.py
print __name__
# output
__main__

当文件使用包模块的方式运行的时候,文件的__name__属性则为模块的路径(从top level script的目录开始),包模块的例子目录结构如下:

├── main.py
└── pac
├── __init__.py
└── moduleA.py

笔者将直接运行main.py文件,代码如下:

## main.py
from pac import moduleA
## moduleA.py
print __name__
## output
pac.moduleA

这两种运行方式还有不同的地方是,当使用top level script的方式运行的时候是不会生成字节码的(即.pyc文件),而通过包模块的方式则会生成字节码。


Relative Import And Absolute Import

假设如下的import语句:

import string

这个string是当前目录下的string模块呢,还是在标准库的string模块呢?在早期的Python中,当使用import语句的时候,都会优先寻找目录内的模块,因此这就是隐式相对导入。

但是在有同名模块的情况下,如果还想引用标准库中的string模块那该怎么办?因此Python实现了绝对导入,在绝对导入的模式下,当使用import string的时候,就会优先搜索当前目录以外的模块。绝对导入模式是Python3默认采取的包导入方式,其实这种方式在Python2.5及以上版本就已经实现,要想使用只需加上:

from __future__ import absolute_import
关于隐式相对导入于绝对导入的例子如下:
包结构:
├── main.py
└── pac
├── __init__.py
├── __init__.pyc
├── explicit_import.py
├── explicit_import.pyc
├── implicit_import.py
├── implicit_import.pyc
├── string.py
└── string.pyc

代码如下:

# main.py
from pac import implicit_import
from pac import explicit_import
# explicit_import.py
from __future__ import absolute_import
import string
print string.digits
# implicit_import.py
import string
print string.digits
# string.py
digits = '2333'
## output
2333(relative import)
0123456789(absolute import)

绝对导入还有一种使用方法,比如在explicit_import.py中可以通过:

from pac.implicit_import import *

来引用implicit_import文件中的变量。

explicit relative import

虽然绝对导入能够完成相对导入的所有功能,但是显式的相对导入也是可以接受的。当使用.语法的时候就是使用相对导入:

# 导入当前目录下的string模块
# right
from . import string
# wrong
import .string
至于下面的导入方法错误的原因,这是因为Python语法不支持的缘故。
同时值得注意的是,显式的相对导入是根据模块的__name__属性来确定相对位置的,因此如果是在top level script中,显式相对导入并不能使用,会报出如下错误:
ValueError: Attempted relative import in non-package

当然,在PEP 366 – Main module explicit relative imports中,也给出了在Python中执行非包内的模块(作为top level脚本执行)使用显示相对导入的方法:在执行python命令时加上-m选项,此时就会启用模块的__package__属性。

详细的关于相对导入与绝对导入参考:PEP 328 – Imports: Multi-Line and Absolute/Relative。

Ubuntu 14.04安装Python 3.3.5 http://www.linuxidc.com/Linux/2014-05/101481.htm

CentOS上源码安装Python3.4 http://www.codesec.net/Linux/2015-01/111870.htm

《Python核心编程 第二版》.(Wesley J. Chun ).[高清PDF中文版] http://www.codesec.net/Linux/2013-06/85425.htm
《Python开发技术详解》.( 周伟,宗杰).[高清PDF扫描版+随书视频+代码] http://www.codesec.net/Linux/2013-11/92693.htm

Python脚本获取Linux系统信息 http://www.codesec.net/Linux/2013-08/88531.htm

在Ubuntu下用Python搭建桌面算法交易研究环境 http://www.codesec.net/Linux/2013-11/92534.htm

Python 语言的发展简史 http://www.codesec.net/Linux/2014-09/107206.htm


本文地址:http://www.codesec.net/Linux/2016-10/135742.htm


Python的包导入机制

本文系统(linux)相关术语:linux系统 鸟哥的linux私房菜 linux命令大全 linux操作系统

主题: LinuxPythonUbuntu算法其实变量
分页:12
转载请注明
本文标题:Python的包导入机制
本站链接:http://www.codesec.net/view/483429.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 系统(linux) | 评论(0) | 阅读(17)