模块的认识
一、模块的介绍
1.什么是模块
模块就是一系列功能的结合体
模块的三种来源:
1.>内置的(python解释器自带的)
2.>第三方的(别人写的)
3.>自定义的(自己写的)
模块的四种表现形式:
1.>使用python编写的py文件(一个py文件也可以称之为模块)
2.>已被编译为共享库DLL的C或C++扩展
3.>把一系列模块组织到一起的文件夹
4.>使用C编写并连接到python解释器的内置模块
2.为什么要使用模块
1.>用别人写好的模块(内置的,第三方的):典型的拿来主义,极大地提高开发效率
2.>使用自己写的模块(自定义的):当程序比较庞大的时候,你的项目不可能只在一个py文件中,
当那么多文件都需要使用相同的方法的时候,可以将该公共的方法写到一个py文件中,其他文件
以模块的形式导过去直接调用即可,从文件级别组织程序,这样更方便管理。
3.如何使用模块
注意:
1.一定要区分开执行文件和被导入文件
2.通常模块的句式要写在文件的开头
二、模块使用之import
以md.py为例来介绍模块的使用:文件名md.py,模块名md
print('from the md.py') money: int=1000 def read1(): print('md模块:',money) def read2(): print('md模块') read1() def change(): global money money=0
此图片为执行文件的显示
此图为执行文件的打印结果
当右键运行执行文件xy.py会先创建一个xy.py的名称空间
首次导入模块(md.py)做的三件事:
1.执行md.py文件
2.运行md.py文件中的代码,将产生的名字与值存放到md.py的名称空间中
3.在执行文件中产生一个指向名称空间的名字(md)
被导入的模块有独立的名称空间
访问模块中的名字指向的值
使用import导入模块,访问模块名称空间的名字统一句式:模块名.名字
如:print(md.money)
那么如果在执行文件中出现一个变量,与模块中的一样会打印什么结果呢?
由上图可以看出;
打印的结果还是模块中的值为1000
这是为什呢?
1.指名道姓的访问模块中的名字,永远不会执行文件中的名字冲突
2.如果想访问模块中的名字,必须用模块名.名字的方式
注意:
1.只要能拿到函数名,无论在哪里都可以通过加括号来电用这个函数
2.函数在定义阶段,名族查找就已经固定,不会因为调用位置变化而改变
为模块起别名
1 import md as sm 2 print(sm.money)
import支持一行导入多个模块,但不推荐使用
import time,os,sys
三、模块使用之from...import...
1.from...import...
from md import money
2.如果当前文件有重名,会有覆盖效果
from md import money # 使用模块取money这个值 money = 9999 # 将当前位置的money绑定成了9999 print(money) # 打印当前的名字 结果就为9999,所以结果就不会变成模块中money的值,因为在执行文件当中money = 9999这个值已经把模块中的值覆盖了
3.form...import...句式
1.访问模块中的名字不需要加模块名前缀
2.在访问模块中的名字可能会与当前执行文件中的名字冲突
4.补充
from md import * # 可以一次性将模块中的名字全部加载出 不推荐使用
__all__可以指定当所在py文件被当做模块导入的时候,可以限制导入者能拿到名字的个数 如: __all__=['money','read1'] # 这样在另外一个文件中用from md import *就这能导入列表中规定的两个名字
四、循环导入及解决思路
1.示范文件
#m1.py print('正在导入m1') from m2 import y x='m1' #m2.py print('正在导入m2') from m1 import x y='m2' #run.py import m1
2.执行结果
3.解决思路
问题分析 首先执行run.py,执行import m1,开始导入m1并运行其内部代码, 打印内容"正在导入m1". 执行from m2 import y 开始导入m2并运行其内部代码, 打印内容“正在导入m2”. 执行from m1 import x,由于m1已经被导入过了, 所以不会重新导入,所以直接去m1中拿x, 然而x此时并没有存在于m1中,所以报错
方式1:将导入语句放在文件最下方 #m1.py print('正在导入m1') x='m1' from m2 import y #m2.py print('正在导入m2') y='m2' from m1 import x #run.py import m1
方式2:函数内导入模块
#m1.py print('正在导入m1') def f1(): from m2 import y print(x,y) x = 'm1' # f1()
#m2.py print('正在导入m2') def f2(): from m1 import x print(x,y) y = 'm2'
#run.py import m1 m1.f1()
打印结果
正在导入m1
正在导入m2
五、区分py文件的类型
1.当文件被当做文件的时候__name__打印的结果是__main__
2.当文件被当做模块导入的时候__name__打印的结果是模块名(没有后缀)
六、模块的查找顺序
1.先从内存中找
2.内置中找
3.sys.path中找(类似于环境变量):
一定要分清楚执行文件与被导入文件
是一个大列表里面放了一堆文件路径,第一个文件路径永远是执行文件所在的文件夹
#模块的查找顺序 1、在第一次导入某个模块时,会先检查该模块是否已经被加载到内存中(当前执行文件的名称空间对应的内存),如果有则直接引用 ps:python解释器在启动时会自动加载一些模块到内存中,可以使用sys.modules查看 2、如果没有,解释器则会查找同名的内建模块 3、如果还没有找到就从sys.path给出的目录列表中依次寻找spam.py文件。
注意:
py文件名不能与模块文件名重名
七、绝对导入与相对导入
1.绝对导入
所有的模块导入必须以执行文件为准
绝对倒入必须依据执行文件所在的文件夹路径为准
无论在执行文件中还是在被导入文件都适用
2.相对导入
.代表的当前路径
..代表上一级路径
...代表上上级路径
3.注意:
相对导入不能在执行文件中使用
相对导入只能在被导入的模块中使用,使用相对导入,就不需要考虑
执行文件到底是谁,只需要知道模块与模块之间的路径
八、软件开发目录规范
1.项目的启动文件通常放在两个地方
1.>bin文件下
2.>直接在项目根目录
2.项目名
bin文件夹:start.py
conf文件夹:setting.py项目配置文件
core文件夹:src.py项目核心逻辑文件
db文件夹:项目存储数据库
lib文件夹:common.py项目所用到的公共功能
log文件夹:log.log项目的日志文件
readme文本文件:介绍项目
3.项目启动代码
import m1 import sys import os BASE_DIR = os.path.dirname(os.path.dirname(__file__)) from core import src if __name__ == '__main__': src.run