您的位置:首页 > 编程语言 > Python开发

25 Python 包

2017-01-01 16:32 295 查看

Python 包

包,包含一组模块和
__init__.py
的文件夹。

这项技术有助于解决不同应用程序中使用的模块名称之间命名空间冲突的问题。包是通过使用与其相同的名称创建目录,并在该目录中创建
__init__.py
。如果需要,可以向该目录中放入其他源文件、编译后的扩展和子包。

按如下方式组织一个包



只要第一次导入包中的任何部分,就会执行相应的
__init__.py
中的代码。
这个文件可以为空,也可以包含可执行代码。在import语句执行期间,遇到的所有
__init__.py
都会执行。如
import packet.A.a
,先执行packet目录下的
__init__.py
,然后执行A目录下的
__init__.py


在使用包时,如果导入的是模块名,则需要注意,

导入的是包中的模块,正常使用即可。如

packet/__init__.py
packet/A/__init__.py
均为空

from packet.A import a   #正常,使用a中的属性,a.attr即可


import packet.A.a as a       #正常,使用a.attr即可


from packet.A.a import * #正常,直接使用a中的属性attr即可


导入的是包,则需要修改
__init__.py
__init__.py不能为空


使用该语句时,通常希望将某个包中的所有子模块导入当前命名空间中。但是,由于各个操作系统之间的文件名约定不同(尤其是区分大小写上),Python无法准确地确定各个模块的具体内容。所以,导入包时只会导入与包同路径下的
__init__.py
中的内容。
可利用
__all__


测试如下

packet/__init__.py
为空时,如

import packet
packet.d.attr   #AttributeError: 'module' object has no attribute 'd'
packet.A.a.attr #AttributeError: 'module' object has no attribute 'A'


from packet import A
print A.a.attr  #AttributeError: 'module' object has no attribute 'a'


修改
packet/__init__.py
,,内容如下(此时
packet/A/__init__.py
仍为空)

import d
import A


import packet
packet.d.attr   #正常
packet.A.a.attr #AttributeError: 'module' object has no attribute 'a',找到了包A但是找不到模块a.py


from packet import A
print A.a.attr  #AttributeError: 'module' object has no attribute 'a'


继续修改
packet/A/__init__.py
,内容如下

import a


import packet
packet.d.attr   #正常
packet.A.a.attr #正常


from packet import A
print A.a.attr  #正常


相对导入

如果包中的模块想要使用同一个包中的模块,如
packet/A/a.py想要导入packet/d.py或者packet/B/d.py
。为此,需要完全限定名称(如packet.B.d,绝对路径导入)或使用包的相对导入,如

packet/A/a.py导入packet/A/d.py ,packet/A/a.py内容如下

相对导入

from . import d                #.代表当前路径


绝对导入

import packet.A.d as d


packet/A/a.py导入packet/d.py,packet/A/a.py内容如下

相对导入

from .. import d               #..代表上一层路径


绝对导入

import packet.d as d


packet/A/a.py导入packet/B/d.py,packet/A/a.py内容如下

相对导入

from ..B import d              #..B代表上层路径中的B


绝对导入

import packet.B.d as d


在包中,要避免使用import module来导入包的子模块,在早期的Python版本中,无法确定import module语句引用的是标准库模块还是包的子模块。相对导入和绝对导入能更加清楚的表明导入意图。

使用相对导入的注意事项,

相对导入只能使用from module import attr形式的导入语句,import ..B.d这样的语法是不对的;

相对导入只能在包中使用,不能在用户的应用程序中使用相对导入,

因为不论是相对导入还是绝对导入,都是相当于当前模块来说的,对于用户的主应用程序,也就是入口文件,模块名总是为
__main__
, 所以用户的应用程序必须使用绝对导入。package中可以使用相对导入和绝对导入;


使用相对路径import 的Python脚本不能直接运行,要保证这个模块不是入口文件,只有作为被导入的模块才可以使用相对导入。原因正如手册中描述的,所谓相对路径其实就是相对于当前module的路径,如果直接执行脚本,这个module的name就是
__main__
, 而不是module原来的name, 这样相对路径也就不是原来的相对路径了,导入就会失败,出现错误“ValueError: Attempted relative import in non-package” ;




转载请标明出处,原文地址(http://blog.csdn.net/lis_12/article/details/53966799).

如果觉得本文对您有帮助,请点击‘顶’支持一下,您的支持是我写作最大的动力,谢谢。

参考网址:

http://www.itnose.net/detail/6232982.html

http://blog.csdn.net/lis_12/article/details/53574885

http://blog.csdn.net/chinaren0001/article/details/7338041
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息