【有书共读01】《python学习手册》读书笔记十七
第二十三章 模块包
学习目标:
学习python的包导入模型:
明确列出目录路径的部分从而找到模块。
包导入的意义:
在较大的系统中更有意义,简化了导入搜索路径设置,
同名模块的路径不同的区分
python代码的目录统称为 包
就是把计算机上的目录变成另一个python命名空间,属性则是对应于目录中所包含发子目录和模块文件。
包导入基础:
包导入的运作:
在import语句中列举简单文件名的地方,可以改成列出路径的名称,彼此以点号(.)相隔
import dir1.dir2.mod
同理from语句:
from dir1.dir2.mod import x
这些语句中的点号(.)路径是对于机器上目录层次的路径,通过这个路劲可以获得mod.py,
语句中表明机器上有个目录dir1,dir1中有个子目录dir2,dir2中包含了一个mod.py的模块文件
同样意味着:dir1位于某个容器目录dir0中,这个目录可以在python模块搜索路径中找到,
语句所代表的目录结构是:dir0\dir1\dir2\mod.py
容器dir0需要添加在模块搜索路径中(除非这是顶层文件的主目录),就好像dir1是模块文件那样。
包 和 搜索路径设置
python中,import语句中的目录路经只能是以点号(.)间隔的变量,
不能在import语句中使用任何平台特定的路径语法
例:C:\dir1、my documents.dir2 或者../dir1: 什么的
上一个例子中,dir0可以是任意长度并且与平台相关的目录路径,在其下能找到dir1,
而不是像这样的无效语句:import C:\mycode\dir1\dir2\mod
增加 C:\mycode 在python path系统变量中或是.pth文件中(假设他不是这个程序的主目录,就不用这样)
然后写下语句: import dir1.dir2.mod
注意要省略mod.py中的.py否则,编译器则会以为想要查找的是..\mod\py.py文件。
__init__.py包文件
选择包导入,则,包导入语句的路径中的每个目录内都必须有_init_.py文件,否则导入包会失败
就是说我们上个例子中,dir1,dir2中都必须有_init_.py这个文件。
容器目录(dir0)不需要这类文件,因为其本身没有列在import语句中
总之,像这样的目录结构:dir0\dir1\dir2\mod.py
以及这种形式的import语句:import dir1.dir2.mod
都必须遵循下面的规则:
1.dir1和dir2中都含有一个__init__.py文件。
2.dir0是容器,不需要__init__.py文件;如果有,这个文件也会被忽略。
3.dir0(而非dir0\dir1)必须列在模块搜索路径上(就是说,此目录必须是主目录,或者列在python path中)。
__init__.py可以包含python程序代码,就像普通模块文件。
某种程度上就像python的一种声明,但是亦可以完全是空的。
__init__.py文件可以防止有相同名称的 目录 不小心 隐藏 在模块搜索路径中,而之后才出现真正所需要的模块。
没有这层保护,python可能会挑选出和程序代码无关的目录,只因为有一个同名的目录刚好出现在搜索路径上较前的目录内。
包的初始化:
python首次执行某个目录时,会自动执行该目录下__init__.py文件中所有程序代码。
模块命名空间的初始化:
继续上一个例子,导入后,表达式dir1.dir2会运行,返回一个模块对象,
此对象的命名空间包含了dir2的__init__.py文件所赋值的所有变量名。
这类文件为目录(没有实际相配的模块文件)所创建的模块对象提供了命名空间。
from*语句的行为:
高级功能:可以在__init__.py文件内使用_all_列表来定义目录以from*语句形式导入时,需要导入什么。
在_init_.py文件中,__all__列表是指当包(目录)名称使用from*的时候,应该导入的子模块的名称清单。
但是如果没有设置__all__,from*语句不会自动加载想逃于该目录下的子模块。
取而代之的是,只加载该目录的__init__.py文件中赋值语句定义的变量名,
包括该文件中程序代码明确导入的任何子模块。
例:__init__.py内的语句from submodule import x ,会让变量名x可以在该目录的命名空间内使用
当你不需要这类文件的时候,也可以让这类文件保持空白。
不过,为了让目录完全导入运作,这类文件就要存在。
包导入实例:
#dir1\__init__.py
print('dir1 init')
x=1
#dir1\dir2\__init__.py
print('dir2 init')
y=2
#dir1\dor2\mod.py
print('in mod.py')
z=3
这里,dir1要么位于我们工作所在的目录(主目录)的子目录,要么位于模块搜索路径中(技术上就是sys.path)的一个目录的子目录。
无论哪一种,dir1的容器都不需要__init__.py文件。
python向下搜索时,import语句会在每个目录首次便利时,执行该目录的初始化文件。
我们用print语句来跟踪他们的执行。
此外,任何以导入的目录也可以传递给reload,来强制该项目重新执行,
reload可以接受点好路径名称,来重载嵌套的目录和文件。
例:
>>>import dir1.dor2.mod
dir1 init
dir2 init
in mod.py
>>>import dir1.dir2.mod
>>>
>>>from imp import reload
>>>reload(dir1)
dir1 init
<module 'dir1' from 'dir1\__init__.pyc'>
>>>
>>>reload(dir1.dir2)
dir2 init
<module 'dir1.dir2.mod' from 'dir1\dir2\__init__.pyc'>
导入后,import语句内的路径会变成脚本的嵌套对象路径。
>>>dir1
<module 'dir1' from 'dir1\__init__.pyc'>
>>>dir1.dir2
<module 'dir1.dir2' from 'dir1\dir2\__init__.pyc'>
>>>dir1.dir2.mod
<module 'dir1.dir2.mod' from 'dir1\dir2\mod.pyc'>
路径上每个目录名成都会变成拇指了模块对象的变量,
而模块对象的命名空间则是由该目录内的__init__.py文件中所有赋值语句进行初始化的。
dir1.x引用了变量x,x就是在dir1\__init__.py中赋值的,
而mod.z引动变量z则是在mod.py内赋值的。
>>>dir1.x
1
>>>dir1.dir2.y
2
>>>dir1.dir2.mod.z
3
包对应的from语句和import语句:
import语句和包一起使用时,有些不方便,因为你必须经常就程序中重新输入路径
例:
>>>dir2.mod
error
>>>mod.z
error
用from语句可以更简单一点:
>>>from dir1.dir2 import mod
dir1 init
dir2 init
in mod.py
>>>mod.z
3
为什么要使用包导入:
好啊,大型程序中基本用的都是包导入
包的相对导入:
没有什么用
#笔记##读书笔记#
学习目标:
学习python的包导入模型:
明确列出目录路径的部分从而找到模块。
包导入的意义:
在较大的系统中更有意义,简化了导入搜索路径设置,
同名模块的路径不同的区分
python代码的目录统称为 包
就是把计算机上的目录变成另一个python命名空间,属性则是对应于目录中所包含发子目录和模块文件。
包导入基础:
包导入的运作:
在import语句中列举简单文件名的地方,可以改成列出路径的名称,彼此以点号(.)相隔
import dir1.dir2.mod
同理from语句:
from dir1.dir2.mod import x
这些语句中的点号(.)路径是对于机器上目录层次的路径,通过这个路劲可以获得mod.py,
语句中表明机器上有个目录dir1,dir1中有个子目录dir2,dir2中包含了一个mod.py的模块文件
同样意味着:dir1位于某个容器目录dir0中,这个目录可以在python模块搜索路径中找到,
语句所代表的目录结构是:dir0\dir1\dir2\mod.py
容器dir0需要添加在模块搜索路径中(除非这是顶层文件的主目录),就好像dir1是模块文件那样。
包 和 搜索路径设置
python中,import语句中的目录路经只能是以点号(.)间隔的变量,
不能在import语句中使用任何平台特定的路径语法
例:C:\dir1、my documents.dir2 或者../dir1: 什么的
上一个例子中,dir0可以是任意长度并且与平台相关的目录路径,在其下能找到dir1,
而不是像这样的无效语句:import C:\mycode\dir1\dir2\mod
增加 C:\mycode 在python path系统变量中或是.pth文件中(假设他不是这个程序的主目录,就不用这样)
然后写下语句: import dir1.dir2.mod
注意要省略mod.py中的.py否则,编译器则会以为想要查找的是..\mod\py.py文件。
__init__.py包文件
选择包导入,则,包导入语句的路径中的每个目录内都必须有_init_.py文件,否则导入包会失败
就是说我们上个例子中,dir1,dir2中都必须有_init_.py这个文件。
容器目录(dir0)不需要这类文件,因为其本身没有列在import语句中
总之,像这样的目录结构:dir0\dir1\dir2\mod.py
以及这种形式的import语句:import dir1.dir2.mod
都必须遵循下面的规则:
1.dir1和dir2中都含有一个__init__.py文件。
2.dir0是容器,不需要__init__.py文件;如果有,这个文件也会被忽略。
3.dir0(而非dir0\dir1)必须列在模块搜索路径上(就是说,此目录必须是主目录,或者列在python path中)。
__init__.py可以包含python程序代码,就像普通模块文件。
某种程度上就像python的一种声明,但是亦可以完全是空的。
__init__.py文件可以防止有相同名称的 目录 不小心 隐藏 在模块搜索路径中,而之后才出现真正所需要的模块。
没有这层保护,python可能会挑选出和程序代码无关的目录,只因为有一个同名的目录刚好出现在搜索路径上较前的目录内。
包的初始化:
python首次执行某个目录时,会自动执行该目录下__init__.py文件中所有程序代码。
模块命名空间的初始化:
继续上一个例子,导入后,表达式dir1.dir2会运行,返回一个模块对象,
此对象的命名空间包含了dir2的__init__.py文件所赋值的所有变量名。
这类文件为目录(没有实际相配的模块文件)所创建的模块对象提供了命名空间。
from*语句的行为:
高级功能:可以在__init__.py文件内使用_all_列表来定义目录以from*语句形式导入时,需要导入什么。
在_init_.py文件中,__all__列表是指当包(目录)名称使用from*的时候,应该导入的子模块的名称清单。
但是如果没有设置__all__,from*语句不会自动加载想逃于该目录下的子模块。
取而代之的是,只加载该目录的__init__.py文件中赋值语句定义的变量名,
包括该文件中程序代码明确导入的任何子模块。
例:__init__.py内的语句from submodule import x ,会让变量名x可以在该目录的命名空间内使用
当你不需要这类文件的时候,也可以让这类文件保持空白。
不过,为了让目录完全导入运作,这类文件就要存在。
包导入实例:
#dir1\__init__.py
print('dir1 init')
x=1
#dir1\dir2\__init__.py
print('dir2 init')
y=2
#dir1\dor2\mod.py
print('in mod.py')
z=3
这里,dir1要么位于我们工作所在的目录(主目录)的子目录,要么位于模块搜索路径中(技术上就是sys.path)的一个目录的子目录。
无论哪一种,dir1的容器都不需要__init__.py文件。
python向下搜索时,import语句会在每个目录首次便利时,执行该目录的初始化文件。
我们用print语句来跟踪他们的执行。
此外,任何以导入的目录也可以传递给reload,来强制该项目重新执行,
reload可以接受点好路径名称,来重载嵌套的目录和文件。
例:
>>>import dir1.dor2.mod
dir1 init
dir2 init
in mod.py
>>>import dir1.dir2.mod
>>>
>>>from imp import reload
>>>reload(dir1)
dir1 init
<module 'dir1' from 'dir1\__init__.pyc'>
>>>
>>>reload(dir1.dir2)
dir2 init
<module 'dir1.dir2.mod' from 'dir1\dir2\__init__.pyc'>
导入后,import语句内的路径会变成脚本的嵌套对象路径。
>>>dir1
<module 'dir1' from 'dir1\__init__.pyc'>
>>>dir1.dir2
<module 'dir1.dir2' from 'dir1\dir2\__init__.pyc'>
>>>dir1.dir2.mod
<module 'dir1.dir2.mod' from 'dir1\dir2\mod.pyc'>
路径上每个目录名成都会变成拇指了模块对象的变量,
而模块对象的命名空间则是由该目录内的__init__.py文件中所有赋值语句进行初始化的。
dir1.x引用了变量x,x就是在dir1\__init__.py中赋值的,
而mod.z引动变量z则是在mod.py内赋值的。
>>>dir1.x
1
>>>dir1.dir2.y
2
>>>dir1.dir2.mod.z
3
包对应的from语句和import语句:
import语句和包一起使用时,有些不方便,因为你必须经常就程序中重新输入路径
例:
>>>dir2.mod
error
>>>mod.z
error
用from语句可以更简单一点:
>>>from dir1.dir2 import mod
dir1 init
dir2 init
in mod.py
>>>mod.z
3
为什么要使用包导入:
好啊,大型程序中基本用的都是包导入
包的相对导入:
没有什么用