模块 模块导入及绝对相对 循环导入问题 链式导入 __name__ 相对导入与绝对导入 软件开发目录规范 跨文件夹导入 模块 模块的使用import 环境变量 模块的使用from .. import .. 链式导入 循环导入问题及解决方法 相对导入与绝对导入 跨文件夹导入 包 软件开发目录规范

1.什么是模块

一系列功能的集合体(注意一个py文件也可以称为模块)。

2.模块的三种来源

内置模块(python解释器自带的);自定义的(自己写的如一个py文件);第三方(别人写的如requests)

3.模块的四种表现形式

 1)使用python编写的.py文件
 2)把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该文件夹称之为包)
 3)使用C编写并链接到python解释器的内置模块
 4)已被编译为共享库或DLL的C或C++扩展

4.为什么要使用模块(提高开发效率):

 1):用别人写好的模块(内置,第三方的):极大地提高了开发效率。

 2):使用自定义模块(自己写的):将多个文件要使用到的相同功能,写到一个文件中直接调用即可

5.注意(******)

一定要区分哪个是执行文件,哪个是被导入文件。

6.模块的加载顺序

内存 > 内置 > sys.path (安装环境变量中路径的先后顺序逐一加载)

7.执行文件和模块的值变化

1.执行文件导入模块的属性和方法,类似于函数中的形参和实参

2.不可变类型,形参发生重指向,实参不变
  可变类型,形参发生值的内部变化,实参变,两个指向的是同一个地址
3.可变类型,变都变。
   不可变类型,你变我不变

模块的使用import

1.语法

import  模块名

import 模块名 as别名

2.使用import语法首次导入模块完成的三件事:

# 1.将被导入的模块编译形成对应的pyc文件
# 2.进入模块,从上执行执行模块中的代码,将产生的所有名字存放在该模块文件的全局名称空间中
# 3.在使用模块的文件中,产生一个与模块名(模块文件名)同名的名字,指向模块的全局名称空间

# 再次导入时 不再执行导入模块的前两步,只会走第三步:在当前模块中产生一个名字,指向第一次导入在内存中产生的全局名称空间

3.使用impo语法访问使用模块的方法和属性:

模块名.属性名

 4.注意

1.指名道姓的访问模块中的名字 永远不会与执行文件中的名字冲突

2.你如果想访问模块中名字 必须用:模块名.名字的方式

3.起别名:import  模块名  as  别名

4. 重点:导入一旦起别名,原模块名变量失效,本质只产生了别名变量指向模块文件的全局名称空间来获取功能

环境变量

1.什么是环境变量

1.环境变量:存放路径的list,第一位默认一定是当前执行文件所在的路径
import sys
sys.path #就是环境变量
2.导入一个模块只要保证模块所在的文件夹路径,在所执行文件的环境变量中可直接导入

模块 模块导入及绝对相对 循环导入问题  链式导入  __name__  相对导入与绝对导入 软件开发目录规范 跨文件夹导入
模块
模块的使用import
环境变量
模块的使用from .. import ..
链式导入
循环导入问题及解决方法
相对导入与绝对导入
跨文件夹导入
包
软件开发目录规范

 2.环境变量添加

import sys
sys.path
# 清空环境变量:所有导入都不能使用了
sys.path.clear()

# 添加指定路径到环境变量
sys.path.append(r"路径")
sys.path.insert(索引,r"路径")

注意:安装环境变量中路径的先后顺序逐一加载

模块的使用from .. import ..

1.语法:

from 模块名 import 模块中的名字1, ..., 模块中的名字n
from 模块名 import 名字 as 别名

2.使用from .. import ..语法首次导入模块完成的三件事

1.将被导入的模块编译形成对应的pyc文件
2.进入模块,从上执行执行模块中的代码,将产生的所有名字存放在该模块文件的全局名称空间中
3.在导入模块的文件中形成(一个或多个)名字指向模块全局名称空间中的(一个或多个)具体名字
注意:再次导入时 不再执行导入模块的前两步,只会走第三步:在当前模块中产生一个名字,指向第一次导入在内存中产生的全局名称空间

3.注意事项

1.from 模块名 import * :表示将模块中的所有功能和名字全部导入;不建议这样使用容易浪费资源和执行文件中出现同名的功能容易混乱。

2.利用from...import...句式
 1.访问模块中的名字不需要加模块名前缀
 2.在访问模块中的名字可能会与当前执行文件中的名字冲突

4.from...import *

1.模块中默认会添加 __all__ ,__all__ 就是管理模块中能被 * 导入的变量们2.__all__可以自定义,自定义 * 能导入的变量们, __all__的list中名字全部可以自定义
__all__ = ['a', 'b', 'c', 'd_', '_e']


3.系统默认添加的__all__中不会纳入 _开头的名字
#       -- 所以默认在外界通过from...import *无法导入_开头的名字
#        -- _开头的名字对from...import *是隐藏的,指名道姓依然可以被外界导入使用

模块 模块导入及绝对相对 循环导入问题  链式导入  __name__  相对导入与绝对导入 软件开发目录规范 跨文件夹导入
模块
模块的使用import
环境变量
模块的使用from .. import ..
链式导入
循环导入问题及解决方法
相对导入与绝对导入
跨文件夹导入
包
软件开发目录规范

链式导入

# t1导入m1,m1导入m2,m2导入m3

# 执行流程:右键执行t1,在t1导入m1模块的地方直接进入m1,去执行m1,同理在m1执行过程中遇到导入m2,会马上进入m2,去执行m2,一直到m3,m3执行完毕,会回到m2中导入m3的语句,接着往下执行m2,
m2执行完毕回到m1,以此类推返回到t1
# 在整个执行流程中,遇到任何模块的二次导入,都是直接引用内存中的名称空间,不会再次进入模块

循环导入问题及解决方法

1.什么是循环导入及产生问题原因:

多个模块之间相互导入没办法正确获得的对应的功能;如:名字没有产生就使用名字,程序设计的不合理
循环导入问题应该在程序设计阶段就应该避免

2.示例:

# 问题
# m1.py
import m2
print(m2.y)
x = 666

# m2.py
import m1
print(m2.x)
y = 888

# 解决
# m1.py
x = 666
import m2
print(m2.y)


# m2.py
y = 888
import m1
print(m2.x)

3. 解决循环导入:

1.方式1
    将循环导入的句式写在文件最下方()——————先产生名字,在导入模块
#       -- 将会产生循环导入的模块,导入语法延后 - 延后导入

2.方式2
    函数内导入模块

模块的两种被执行方式 __name__

# 1.一个py文件作为自执行文件,__name__变量的值为 '__main__'
# 2.一个py文件作为模块被导入执行,__name__变量的值为 '文件(模块)名'

# 如何区别两种方式,可以让一个文件可以自执行,也可以被导入执行 共存
# 在这样的py文件中写:
if __name__ == '__main__':
    # 自执行的逻辑 => 因为在文件作为模块使用时 __name__为文件名,不满足条件
    pass

相对导入与绝对导入

绝对导入必须依据执行文件所在的文件夹路径为准
    1.绝对导入无论在执行文件中还是被导入文件都适用
    
相对导入
    .代表的当前路径
    ..代表的上一级路径
    ...代表的是上上一级路径

    注意相对导入不能在执行文件中使用
    相对导入只能在被导入的模块中使用,使用相对导入 就不需要考虑
    执行文件到底是谁 只需要知道模块与模块之间路径关系

跨文件夹导入

# 1.如果a文件夹所在目录在环境变量,a文件夹中的ma模块可以被以下方式导入
import a.ma  |  from a import ma 

# 2.如果a文件夹所在目录在环境变量,a文件夹中的b文件夹的mb模块可以被以下方式导入
import a.b.mb  |  from a.b import mb

# 3.如果a文件夹所在目录在环境变量,a文件夹中的b文件夹的mb模块中的bbb名字要被直接导入 
import a.b.mb.bbb  # 错误:所有.左侧必须是文件夹 *****
from a.b import mb.bbb # 错误:所有.左侧必须是文件夹
from a.b.mb import bbb # 正确

1.什么是包

1.包:一系列模块的集合体,用文件夹来管理一系列有联系功能的模块,该文件夹我们称之为包,文件夹名就是包名

2.包 与 普通文件夹存在区别:包的文件夹中一定存在一个__init__.py文件
        -- py2:必须创建  py3:建议创建,不创建系统会自动创建

2.

# __init__.py文件
# 1)产生一个全局名称空间,提供给包的,就代表包的名称空间
# 2)管理 包可以直接点出来使用的 名字

# 导包完成的三件事
# 1)编译形成包中__init__.py文件的pyc文件
# 2)执行__init__.py文件,形成一个全局名称空间,将__init__.py文件中所有名字存放其中,该名称空间就代表包的名称空间
# 3)在导包的文件中,产生一个与包名相同的名字,指向包的名称空间(__init__.py文件的全局名称空间)

2.直接使用包中模块

1.如果只是想作为普通文件夹,py3中可以省略__init__文件,本质上文件夹也是包

# 导入和使用和前面一样:1.指名道姓到某一个模块 | 2.指名道姓到某一个模块中的名字

3.包的管理

# 在包中采用相对导入管理模块或模块中的名字
# 在包的__init__.py文件或是包中任意一个模块中
# . 代表当前文件所在目录
# .. 代表当前文件所在目录的上一级目录
# 注:.语法不能出包,因为包外的文件都能自执行,但拥有.开头导入的文件不能自执行

软件开发目录规范

bin: 可执行文件,入口,入口也可以放在项目根目录下
core: 核心代码
db:数据库相关文件
interface:接口
lib:包、模块、第三方文件夹
log:日志
setting:配置
static:静态文件