一、基本概念
模块:
是一个包含你所有定义的函数和变量的文件,后缀名为.py,就是可以将python解释器写的却不能保存的代码用文档保存下来。模块可以被别的程序引用,以使用该模块实现的功能。
包:一种组织方式,通俗的讲就是一个文件夹,其内容由模块和子包组成。
二、导入模块
导入模块的本质就是在当前的.py文件中加载其他模块、包、其他对象来赋值给一个标识符或者自定义其名称。
注意:导入模块不管你执行多少次import,一个模块只能被导入一次,这可以有效的防止导入模块重复无效的执行。
1.import 语句
1.1 import 模块名
找到指定的模块,将其加载和初始化生成模块对象,如果找不到模块抛出ImportError异常
import math
x, y = 2, 3
print(math.pow(x, y))#在使用模块里面的功能时要带上模块的名字
1.2 import 模块名 as name
找到指定模块,将其加载和初始并重新命名为name的模块对象,如果找不到模块也会抛出ImportError异常
import math as m#导入math模块并重命名为m,在下面的使用中就不能用math而要使用重新取的名字m
x, y = 2, 3
print(m.pow(x, y))
1.3 import 模块名 和 import 模块名.功能名区别
例如 import os 加载的是os模块,需要使用的path类必须使用限定名os.path
当前环境能够使用的变量是os
import os.path 加载的是os模块,需要使用必须使用限定名os.path,当前环境的变量是os,能够且只能使用os.path
1.4 import 导入的模块放在全局就是全局的,放在局部里就是局部的 遵循的是变量的规则
示例1:
import os#在全局中导入模块 全局和局部都能使用
if os.path.exists('top.txt'):
os.remove('top.txt')
print('removed top.txt')
else:
with open('top.txt', 'w') as f:
f.write('abcde')
print('writed top.txt')
def file():
if os.path.exists('top1.txt'):
os.remove('top1.txt')
print('removed top1.txt')
else:
with open('top1.txt', 'w') as f:
f.write('abcde')
print('writed top1.txt')
file()
示例2:
def file():
import os#在局部函数中导入模块
if os.path.exists('top.txt'):
os.remove('top.txt')
print('removed file')
else:
with open('top.txt', 'w') as f:
f.write('abcde')
print('writed file')
file()
print(dir())
os.remove('top.txt')#报NameError错误 在file函数中导入的就只能在file中有效
2.from ... import ...语句
2.1 from modelname import name1[,name2[, ... nameN]
从模块modelname中导入部分指定的name1,name2,...,nameN成员
from os.path import exists
if exists('top1.txt'):
print('top1.txt exists')
else:
print('not found')
2.2 from modelname import *
从模块modelname中导入所有成员,虽然这是一个简单的导入一个模块中所有的成员,但是这种方法不建议过多的使用
2.3 from modelname import name1 as name
从模块modelname中导入name1成员并重命名为name
from os.path import exists as e
if e('top1.txt'):
print('top1.txt exists')
else:
print('not found')
三、标准模块
python本身带有一些标准的模块库,有些模块直接被构建在解析器里,这些虽然不是一些语言内置的功能,但是他却能很高效的使用,
甚至是系统级调用也没问题。这些组件会根据不同的操作系统进行不同形式的配置,比如 winreg 这个模块就只会提供给 Windows 系统。
应该注意到这有一个特别的模块 sys,它内置在每一个 Python解析器中。变量 sys.ps1 和 sys.ps2定义了主提示符和副提示符所对应的字符串
import sys
print(dir()) #当前环境可以使用的变量,返回的是一个列表
print(global()) #当前环境可以使用的的全局变量
print(local()) #当前环境可以使用的本地变量
print(__name__) #取当前模块名称,在当前模块运行即__main__模块
print(sys.path) #变量的查找顺序
print(sys.modules) #当前加载的模块
print(moudle.__dict__) #模块的属性
print(__file__) #模块的路径
dir()函数:获取模块里定义过的成员
import random
print(dir())
#['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'random']
reload()函数:重新加载模块
当一个模块被夹在到一个模块中,他只能执行一次,如果你想让他重新执行就可以使用reload(模块名).
四、自定义模块
顾名思义,就是自己写的.py文件,将相同类型功能的代码组织在一起,将其他的模块引用到这个文件中的对象。
命名规则:
模块名就是文件名
模块名必须符合标识符的要求,非数字开头的字母数字和下划线组合
切记不要使用系统的模块名,避免相互冲突
通过模块名全为小写、下划线来分割
fibo.py文件
def fib(n):# 定义到 n的斐波那契数列
a,b = 0,1
while b < n:
print(b, end=' ')
a, b = b, a + b
print()
def fib2(n):# 返回到 n的斐波那契数列
result = []
a, b = 0, 1
while b < n:
result.append(b)
a, b = b, a + b
return result
test.py文件
import fibo#导入模块也可以使用上面讲到的其他方式
print(fibo.__dict__.keys())
print(fibo.fib(10))
print(fibo.fib2(20))
五、模块的运行
当标准输入和运行脚本的时候,实际上是运行的__main__(在哪个.py文件运行哪个就是主模块__main__)
当test2.py作为主模块时,import test1 会加载test1;
此时运行test2,test1会被加载,这种情况下test1的模块名为test1,进入else字句;
应用场景:
1、可以用于非主模块的功能测试,将测试代码写入if __name__ == '__main__'中,然后以非主模块运行,则运行的是测试代码;而当真正的主模块运行的时候,运行的是业务代码;
2、主模块变更,当前主模块没有封装;
在需要进行主模块变更时,import当前主模块,运行新的主模块时,老的主模块会一并运行;
代码如下:
test1.py
if __name__ == '__main__':
print('===========')
print('我是{}'.format(__name__))
print('可以写代码')
else:
print('===========')
print('我是{}'.format(__name__))
class Test(object):
def __init__(self, x, y):
self.x = x
self.y = y
def show(self):
return self.x, self.y
t = Test(5, 6)
a = 100
b = 200
print('===========')
test2.py#主模块
import test1
主模块变更后:
test1.py不变
test2.py#原主模块
if __name__ == '__main__':
import test1
print(test1.a)
else:
a = 1000
b = 2000
test3.py#新主模块
import test1
import test2
print(test2.a)
print(test1.a)