ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python进阶与拾遗2:Python中的包

2021-02-28 13:02:27  阅读:262  来源: 互联网

标签:__ 进阶 Python doc py 拾遗 导入 import main


Python进阶与拾遗2:Python中的包


本篇博文,主要总结Python中的包。在Python的大型工程中,包是常用的代码管理工具,用于管理上一讲中的 模块,下面开始干货。

包相关概念

包定义

  1. Python代码的目录称为包
  2. 包导入是把计算机上的目录变成另一个Python命名空间,而属性对应于目录中包含的子目录和模块文件。

使用包的好处

  1. 包导入提供了程序文件的目录信息,因此可以轻松地找到文件,从而作为组织工具来使用。
  2. 大幅简化PYTHONPATH和.pth文件搜索路径设置。
  3. 包导入让你想导入的文件更明确,从而解决模糊性

包的常见使用

包导入的用法

  1. 在import和from中,采用点号分隔目录路径。注意,需要读取两个或两个以上路径内的同名属性时,需要使用import,不能使用from。
import dir1.dir2.mod
from dir1.dir2.mod import x
# 读取同名属性
import doc1.file
import doc2.file
doc1.file.f()
doc2.file.f()
  1. import语句中的目录路径是平台不相关,只能是以点号分隔的变量,不能在import语句中使用任何平台特定的语法。比如C:/file 或者My Doc.file(包含空格)。要实现上述功能,可以将相关目录添加到sys.path列表中,PYTHONPATH环境变量或者.pth文件中。

包导入的__init__.py文件

包导入语句的路径中每个目录内必须有一个__init__.py文件,否则会失败。这个文件可以包含Python代码,也可以是空的。作用如下:

  1. 包的初始化。Python首次导入某个目录时,会自动执行该目录下的__init__.py文件中的所有程序代码。

比如,在工程路径下有一个doc_1文件夹,里面有一个__init__.py和一个a.py:

# __init__.py(空)
# a.py
X = 88

在工程的与doc_1文件夹平级的执行main.py文件中:

from doc_1 import a
def main():
    print(a.X) # 88

if __name__ == '__main__':
    main()

更改__init__.py和a.py:

# __init__.py
Y = 99
# a.py
X = 88

在工程的与doc_1文件夹平级的执行main.py文件中:

import doc_1
from doc_1 import a
def main():
    print(doc_1.Y) # 99
    print(a.X) # 88

if __name__ == '__main__':
    main()
  1. 模块命名空间初始化。在包导入的模型中,脚本内的目录路径,在导入后会变成真实的嵌套对象路径。在导入后,会返回一个模块对象,此对象的命名空间中包含了包路径中最后的目录中的__init__.py文件所赋值的所有变量名。

  2. 尤其注意,from *语句的行为。
    可以在__init__文件内使用__all__列表定义目录以from *语句形式导入时,需要导出什么。在__init__.py文件中。__all__列表是指当包目录名称使用from *的时候,应该导入的子模块的名称清单。如果没有指定__all__,from *语句不会自动加载嵌套于该目录内的子模块,只加载该目录的__init__.py文件中赋值语句定义的变量名和程序代码明文导入的任何子模块
    比如,在工程路径下有一个doc_1文件夹,里面有一个__init__.py和一个a.py:

# __init__.py(空)
# a.py
X = 88

在工程的与doc_1文件夹平级的执行main.py文件中:

from doc_1 import *
def main():
    # print(a.X) # 报错: NameError: name 'a' is not defined

if __name__ == '__main__':
    main()

更改main.py:

from doc_1 import a
def main():
    print(a.X) # 88

if __name__ == '__main__':
    main()

更改main.py:

from doc_1.a import X
def main():
    print(X) # 88

if __name__ == '__main__':
    main()

更改__init__.py和a.py:

# __init__.py
__all__ = ["a"]
# a.py
X = 88

在工程的与doc_1文件夹平级的执行main.py文件中:

from doc_1 import *
def main():
    print(a.X) # 88

if __name__ == '__main__':
    main()

包的相对导入

包相对导入的用法

  1. 相对导入是用在包自身的内部。包文件导入可以使用和外部导入相同的路径语法,也可以使用相对路径。
  2. from语句后面的点号或连点号(一般都是用点号),表示导入时的搜索路径,并且不会搜索位于导入搜索路径上某处的同名模块,直接效果是包模块覆盖了外部的模块
  3. 相对导入只适用于from语句,import语句无法实现。
  4. 在Python 2.6及之后的版本中,包的代码中的常规导入默认是先相对(先搜索自己的路径)再绝对(sys.path)的搜索路径顺序。而在Python 3.0及之后的版本中,在一个包中导入默认是绝对的,会忽略自身路径并直接在sys.path上面查找。也就是说,在Python 3.0及之后的版本中使用包相对导入,需要显式地指定路径
    比如,在工程路径下有一个doc_1文件夹,里面有一个__init__.py和一个a.py:
# __init__.py
from .a import *
# a.py
X = 88

在工程的与doc_1文件夹平级的执行main.py文件中:

import doc_1
def main():
    print(doc_1.a.X) # 88

if __name__ == '__main__':
    main()

更改main.py:

from doc_1 import a
def main():
    print(a.X) # 88

if __name__ == '__main__':
    main()

更改main.py:

from doc_1.a import *
def main():
    print(X) # 88

if __name__ == '__main__':
    main()

Python 3.0及之后版本的模块查找规则总结

  1. 简单模块名通过搜索sys.path路径列表上的每个目录来查找,从左到右进行。
  2. 包是一个带有特殊的__init__.py文件的Python模块的直接目录。这使得一个导入中可以使用A.B.C目录路径语法。A总是相对于sys.path的常规模块导入搜索,B是A中另一个包子目录,C是一个模块或B中的其他可导入项。
  3. 在一个包文件中,常规的import语句使用和其他地方的导入一样的sys.path搜索规则。如果使用相对路径,就不使用常规的sys.path查找,仅在指定的相对路径中查找如果没有使用相对路径,就只在sys.path中查找

以上,欢迎各位读者朋友提出意见或建议。

欢迎阅读笔者后续博客,各位读者朋友的支持与鼓励是我最大的动力!

written by jiong
江山代有才人出,
各领风骚数百年。

标签:__,进阶,Python,doc,py,拾遗,导入,import,main
来源: https://blog.csdn.net/jiongnima/article/details/114212896

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有