文章目录
模块
什么是模块
模块就是一个功能的集合体,不是用来直接运行,而是用来被导入使用的
模块三大来源
1 内置的模块
2 第三方模块
3 自定义的模块
模块的四种形式
1 使用python编写的.py文件一个python文件本身就一个模块,文件名m.py,模块名叫m
2 把一系列模块组织到一起的文件夹(注:文件夹下有一个_init_.py文件,该文件夹称之为包)
3 已被编译为共享库或DLL的C或C++扩展
4 使用C编写并链接到python解释器的内置模块
为何有用模块
1 使用别人的模块:内置与第三的模块拿来就用,无需定义,这种拿来主义,可以极大地提升自己的开发效率
2 自定义的模块:可以将程序的各部分功能提取出来放到一模块中为大家共享使用。好处是减少了代码冗余,程序组织结构更加清晰
导入模块发生的事情、
1、触发被导入的模块的运行,产生一个模块的名称空间,把模块的名字都丢进去
2、会在当前执行文件中得到一个名字spam,该名字是指向被导入模块产生的名称空间
之后的导入,都是直接引用首次导入产生的spam.py名称空间,不会重复执行代码
# spam.py
print('from the spam.py')
__all__ = ['money', 'read1']
money = 1000
def read1():
print('spam模块:', money)
def read2():
print('spam模块')
read1()
def change():
global money
money = 0
# txst.py
import spam
import spam
import spam # 多余的import 不会执行
print(spam.money)
money = 2000
print(money)
print(spam.money)
spam.read1()
一行导入多个模块
如:import spam,m1,m2,m3
如:from spam import money,read1
为导入的模块起别名
如:import dasasdsdfswads as
如:from spam import read1 as f1
自定义模块的命名应该采用纯小写+下划线的风格
可以在函数内导入模块
def func():
import foo
import和from import差别
Import时不会和本地的文件中的变量函数名冲突,模块名,就能使用,但是这种方法会一次性导入该模块中所有的,比较占内存
from+Import 直接使用变量函数名就可以,但是如果本地文件中有相同的名字会发生冲突,一般注意一点就没问题,想用什么导入什么, 相比上面的会节约许多内存
# 使用上面的spam.py
from spam import read1,read2,money # 没有change 所以下面运行change会报错
print(money)
read1()
print(read1)
print(read2)
money=111
print(money)
read1()
# read2 = 3333 read2替换了上面的spam.read2
# read2() # 报错 替换的read2 不是函数
# change() #报错 因为上面form导入没有change()
from spam import * # 先把上面代码全注释了 *代表取spam中所有名字
# 在spam中添加__all__ = ['money', 'read1'] *就只取这两个 取不到read2、change 运行报错
print(money)
print(read1)
print(read2) # 报错
print(change) # 报错
循环导入问题
#示范文件内容如下
#m1.py
print('正在导入m1')
from m2 import y
x='m1'
#m2.py
print('正在导入m2')
from m1 import x
y='m2'
#run.py
import m1
#测试一
执行run.py会抛出异常
正在导入m1
正在导入m2
Traceback (most recent call last):
File "/Users/linhaifeng/PycharmProjects/pro01/1 aaaa练习目录/aa.py", line 1, in <module>
import m1
File "/Users/linhaifeng/PycharmProjects/pro01/1 aaaa练习目录/m1.py", line 2, in <module>
from m2 import y
File "/Users/linhaifeng/PycharmProjects/pro01/1 aaaa练习目录/m2.py", line 2, in <module>
from m1 import x
ImportError: cannot import name 'x'
#测试一结果分析
先执行run.py--->执行import m1,开始导入m1并运行其内部代码--->打印内容"正在导入m1"
--->执行from m2 import y 开始导入m2并运行其内部代码--->打印内容“正在导入m2”--->执行from m1 import x,由于m1已经被导入过了,所以不会重新导入,所以直接去m1中拿x,然而x此时并没有存在于m1中,所以报错
#测试二:执行文件不等于导入文件,比如执行m1.py不等于导入了m1
直接执行m1.py抛出异常
正在导入m1
正在导入m2
正在导入m1
Traceback (most recent call last):
File "/Users/linhaifeng/PycharmProjects/pro01/1 aaaa练习目录/m1.py", line 2, in <module>
from m2 import y
File "/Users/linhaifeng/PycharmProjects/pro01/1 aaaa练习目录/m2.py", line 2, in <module>
from m1 import x
File "/Users/linhaifeng/PycharmProjects/pro01/1 aaaa练习目录/m1.py", line 2, in <module>
from m2 import y
ImportError: cannot import name 'y'
#测试二分析
执行m1.py,打印“正在导入m1”,执行from m2 import y ,导入m2进而执行m2.py内部代码--->打印"正在导入m2",执行from m1 import x,此时m1是第一次被导入,执行m1.py并不等于导入了m1,于是开始导入m1并执行其内部代码--->打印"正在导入m1",执行from m1 import y,由于m1已经被导入过了,所以无需继续导入而直接问m2要y,然而y此时并没有存在于m2中所以报错
解决方法
方法一:导入语句放到最后
#m1.py
print('正在导入m1')
x='m1'
from m2 import y
#m2.py
print('正在导入m2')
y='m2'
from m1 import x
方法二:导入语句放到函数中
#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()
区分python文件的两种用途
1、直接运行。脚本,一个文件就是整个程序,用来被执行
2、被当做模块导入。模块,文件中存放着一堆功能,用来被导入使用
print(_name_) # 当文件被当做脚本执行时,__name__值为’_main_’
print(_name_) # 当文件被当做模块导入时,__name__值为’模块名’
# aaa.py
print('__name__') # 当在该文件下运行时 出现的是__main__
# 作用:用来控制.py文件在不同的应用场景下执行不同的逻辑
# main+回车键 会直接出现if __name__ == '__main__':
if __name__ == '__main__':
print("文件被当作脚本执行时要做的事情")
# __main__
# 文件被当作脚本执行时要做的事情
# bbb.py
import aaa
# 该文件下运行时 会出现main
# main
模块的搜索路径与查找优先级
无论是import还是from…import在导入模块时都涉及到查找问题
优先级:
1、内存(内置模块)
2、硬盘:按照sys.path中存放的文件的顺序依次查找要导入的模块
模块的查找顺序是:内存中已经加载的模块->内置模块->sys.path路径中包含的模块
模块的搜索路径
1)先从内存中已经导入的模块里找
# mmm.py中写着
# def f1():
# print('mmm.f1')
mmm
mmm.f1()
import time
time.sleep(15)
print('='*50)
# 将mmm.py删了 还是能找到 因为还在内存中
import mmm
mmm.f1()
2)然后再查找内置的模块
# import time # 内置模块
# print(time)
#
import sys
# print(sys.modules) # 查看已有的内置模块 sys.modules查看已经加载到内存中的模块
print(sys.path) # sys.path是一个python搜索模块的路径列表:
# 当前执行文件所在的文件夹
import logging
print(logging)
3)最后去sys.path列表中存放的多个文件夹依次检索
示例1:
import sys
# 找bbb.py就把bbb.py的文件夹添加到环境变量中
# bbb.py在day17.aaa.ccc中
sys.path.append(r'/Users/gj/Desktop/pycharm_space/s15/day16/aaa/ccc')
# 可以是其他路径 不需要同一个文件下
import bbb
bbb.f1()
from mmm import f1
# 示例2:
import sys
print(sys.path)
import day17.aaa.ccc.bbb as b
# 同一个根目录 文件夹下
b.f1()
from aaa.ccc import bbb # aaa和该文件在同一个根目录
bbb.f1()
python命名规范
PYTHON命名规范
1.项目名称
首字母大写+大写式驼峰,
ProjectName
2.模块名和包名
全部小写+下划线驼峰
module_name package_name
3.类名称,异常
首字母大写+大写式驼峰,
class ClassName: ,ExceptionName
4.全局变量、常量
全部使用大写字母+下划线驼峰
GLOBAL_VAR_NAME,CONSTANT_NAME
5.方法名,函数名,其余变量,参数,实例
全部小写+下划线驼峰
method_name,function_name,instance_var_name, function_parameter_name, local_var_name
6.处理计数器外,不使用单字母命名