1 模块module
1.1 模块是什么
模块是包含一系列的变量,函数,类等程序组
模块通常是一个文件,以.py结尾
1.2 模块的作用
1. 让一些相关的函数,变量,类等有逻辑的组织在一起,使逻辑更加清晰,
2. 模块中的变量,函数和类等可提供给其他模块或程序使用
1.3 模块的分类
1.内置模块(builtins),在解释器的内部,可以直接使用
2.标准库模块,随python的解释器一起安装,可直接使用(有的是用C语言写的,有的是用python写的)
3.第三方模块(通常为开源),需要自己安装
4.用户自定义模块
1.4 模块化编程的优点
1.有利于多人合作开发
2.使代码更加易于维护
3.提高代码的重用率
4.模块话编程有助于解决函数名和变量名冲突问题
1.5 模块的文档字符串
模块内的第一行未赋值给任何变量的字符串为模块的文档字符串,可用help(模块名)来查看
例如在test1.py模块中
''' 这是test.py模块文件 这个模块是学习测试时使用 这个模块*有 个变量,其中函数变量有 个 ''' def fun1(a,b): a = 1 b = 2 pass def fun2(m,n): pass para1 = "a" para2 = "b" c = map(fun1,[1,2]) print("test1模块被调用了")
经过如下操作
>>> import test1 test1模块被调用了 >>> help(test1)
可以得到下面的帮助页面
Help on module test1: NAME test1 - 这是test.py模块文件 DESCRIPTION 这个模块是学习测试时使用 这个模块*有 个变量,其中函数变量有 个 FUNCTIONS fun1(a, b) fun2(m, n) DATA c = <map object> para1 = 'a' para2 = 'b' FILE /home/tarena/桌面/day13/test1.py ~ (END)
当函数中也有文档字符串时,则放在第一章节说明
2 模块的导入
借助于 import语句
- import XXX
- from XXX import YYY
- from XXX import * # * 表示通配符
2.1 improt 语句
作用:
将模块整体导入到当前的模块作用域(导入之后,通过dir(),可以直接显示该模块名)
语法:
import 模块名1 [as 模块新名1] [,模块名2[as 模块新名2]]....
示例:
导入数学模块
import math #导入数学模块
交互模式下导入数学模式
>>> import math
导入前
>>> dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
导入后
>>> import math >>> dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'math'] >>> import os >>> dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'math', 'os']
dir(obj) 返回所有属性的字符串列表
>>> dir(math) ['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']
help(obj) 查看模块的文档字符串
>>> import math >>> help(math)
会显示模块的文档字符串
Help on built-in module math: NAME math DESCRIPTION This module is always available. It provides access to the mathematical functions defined by the C standard. FUNCTIONS acos(...) acos(x) Return the arc cosine (measured in radians) of x. ....... #此处省略部分函数名称 tanh(...) tanh(x) Return the hyperbolic tangent of x. DATA e = 2.718281828459045 inf = inf nan = nan pi = 3.141592653589793 FILE (built-in) (END)
用法:模块名.属性名
示例1 :打印常量π
>>> import math >>> print(math.pi) 3.141592653589793
注意:必须是小写,没有大写 PI 变量
示例2 :求5的阶乘
>>> import math >>> print(math.factorial(5)) 120
2.2 from improt 语句
作用:
将某模块的一个或多个属性导入到当前模块的作用域
语法:
from 模块名 import 模块属性名1 [as 属性新名1] [,模块名属性2 [as 属性新名2]]
示例:
from math import sin from math import sin, sin, cos from math import pi #将math.pi导入到当前 from math import factorial as f #将factorial 缩写为 f
>>> dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__'] >>> from math import sin >>> dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'sin']
在这里,就可以直接使用 sin 函数
2.3 from import * 语句
作用:
将某模块的所有属性导入到当前模块
语法:
from 模块名 import *
示例:
>>> dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__'] >>> from math import * >>> dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc'] >>> sin(pi/2) 1.0 >>> factorial(5) 120
缺点:
可能会引入模块中的变量与自定义变量冲突.一般将其写在模块的头部,尽量避免导入模块中的变量将自定义变量值改变
2.4 模块加载初步介绍
无论是上述三种( improt 语句 、 from improt 语句 、 from import * 语句 )的那种形式,首次加载时将模块中的变量全部加载。
在模块导入时,无论那种导入方式,模块的所有语句会被执行
如果一个模块已经导入,则再次导入时不会重新执行模块内的语句
如test1.py模块
''' 这是test.py模块文件 这个模块是学习测试时使用 这个模块*有 个变量,其中函数变量有 个 ''' def fun1(a,b): a = 1 b = 2 pass def fun2(m,n): pass para1 = "a" para2 = "b" c = map(fun1,[1,2]) print("test1模块被调用了")
在交互模式下运行
>>> import test1 test1模块被调用了 >>> dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'test1'] >>> dir(test1) ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'c', 'fun1', 'fun2', 'para1', 'para2']
注意:尽管 print() 函数加载了,但是使用 dir() 返回参数列表时,函数变量 print() 和 map() 并没有出现在该模块范围内
为了更明显地显示首次加载模块时是将模块中的“全局”变量均加载一遍,现重新在交互模式下运行
>>> from test1 import fun1 test1模块被调用了 >>> from test1 import para1 >>> dir(test1) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'test1' is not defined >>> dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'fun1', 'para1']
我们可以看到首次调用时有“test1模块被调用了”,但是第二次调用test1模块中的para1时,就没有出现“test1模块被调用了”。
同时我们可以看到查看test1模块的变量时,显示test1没有定义,也即test1没有被引用到当前模块中。
而dir()时,可以显示当前模块的全部变量,则有test1模块中的fun1、para1两个变量调用到当前模块
注意这里面的关系。
模块中的函数也有文档字符串时
''' 这是test.py模块文件 这个模块是学习测试时使用 这个模块*有 个变量,其中函数变量有 个 ''' def fun1(a,b): ''' 这个是fun1测试函数 函数中有两个变量 :param a: :param b: :return: ''' a = 1 b = 2 pass
在交互模式下运行
>>> import test1 >>> help(test1)
则有
Help on module test1: NAME test1 - 这是test.py模块文件 DESCRIPTION 这个模块是学习测试时使用 这个模块*有 个变量,其中函数变量有 个 FUNCTIONS fun1(a, b) 这个是fun1测试函数 函数中有两个变量 :param a: :param b: :return: FILE /home/tarena/桌面/day13/test1.py
在上述案例中同时交互模式下运行
>>>help(test1.fun1)
则有
Help on function fun1 in module test1: fun1(a, b) 这个是fun1测试函数 函数中有两个变量 :param a: :param b: :return: (END)
3 常见的模块(内置&标准库模块)
内置模块有:builtins sys time posix itertools等
标准库模块:random math datetime os xml re functools等
3.1 数学模块 math
在 linux 是内建模块,在 os 中是标准库模块
math.e 自然对数的底
math.pi π
math.sin(x) math.cos(x) math.tan(x) math.asin(x) math.acos(x) math.atan(x) math.degrees(x)# 弧度转角度 math.radians(x)#角度转弧度 math.ceil(x) 向上取整 math.floor(x) 向下取整 math.sqrt(x) 求平方根 math.factorial(x) x的阶乘 math.log(x[,base]) math.log10(x) math.pow(x,y) math.fabs(x)
三角函数中的x是以弧度为单位的
4 模块的属性
4.1 __name__属性:
作用:
1 记录模块名
2 用来判断是否为主模块
说明:
1 对于被导入模块,模块名 = 文件名 - "路径 前缀" 和 .py后缀
2 对于主模块,模块名为"__main__"
示例:
模块test1
def mysum(begin: "开始", end: "结束(不包含end)")-> int: s = 0 for x in range(begin, end): s += x return s def mymax(a, b, c): m = a if b > m: m = b if c > m: m = c return m name1 = "audi" name2 = "tesla" print("test1 模块被加载!") print("test1 模块内的__name__属性的值为:",__name__)
模块test2
import test1 # 导入定义的模块 print("5+6+7+...+ 100的和是:", test1.mysum(5, 101)) print("最大的一个数是:", test1.mymax(1,2,3)) print("test1.name1=", test1.name1) print("test2 模块内的__name__属性的值为:",__name__)
运行test2模块
test1 模块被加载! test1 模块内的__name__属性的值为: test1 5+6+7+...+ 100的和是: 5040 最大的一个数是: 3 test1.name1= audi test2 模块内的__name__属性的值为: __main__
4.2 __doc__属性
用来记录文档字符串, mymod.__doc__
4.3 __file__属性
用来记录模块的文件路径
注意:内建模块没有 __file__ 属性,自定义的模块存在这个属性值
内建模块:
>>> import math >>> math.__file__ Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: module 'math' has no attribute '__file__'
自定义模块
>>> import test1 #导入4.1中的test1模块 test1 模块被加载! test1 模块内的__name__属性的值为: test1 >>> test1.__file__ '/home/tarena/桌面/day13/test1.py'
4.3 __all__属性
用来存放可导出属性的列表,此列表中的元素是字符串
当以 from 模块 import * 这样形式从模块中将变量导入另外一个模块时,在模块开始处加入 __all__ 时,
只有该属性内的值才能被带入。
这样可以避免该模块下的所有变量导入到另外一个模块,过滤掉不想被调用的参数
模块test3
__all__ = ['hello1', 'name1'] def hello1(): pass def hello2(): pass name1 = "模块" name2 = "加载" print("test3 模块被加载!")
交互模式下运行test3模块
>>> from test3 import * test3 模块被加载! >>> dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'hello1', 'name1']
但是当是 import 模块 或 from 模块 import 函数名 时是无效的。
>>> import test3 test3 模块被加载! >>> dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'test3'] >>> dir(test3) ['__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'hello1', 'hello2', 'name1', 'name2']
4.4 时间模块time
写时间相关的模块
UTC 先将a地时间转成UTC时间,再将UTC时间转为b地时间
时间元组(年,月,日,时,分,秒,星期几,元旦开始日,夏令时修正时间)
公元纪年 0000-1-1 0:0:0
计算机元年 1970-1-1 0:0:0
4.5 随机模块random
import random as R
R.random() 返回一个[0,1)之间的随机浮点数
R.uniform(a.b) 返回一个[a.b)之间的随机浮点数
4.6 模块中的隐藏属性
模块中'__'(双下划线)开头,不是以"__"结尾的属性,在 import 模块 或 from 模块 import * 导入时,将不被导入
5 模块的加载
5.1 模块的加载过程
1 先搜索相关路径找模块(.py文件)
2 判断是否有此模块对应的.pyc,如果.pyc文件是有最新的.py文件生成(其实就是比较两文件的最后时间),则直接加载.pyc(compile)
3 如果.pyc文件的生长时间比.py晚,说明.py文件已经修改但没有生成新的.pyc文件,则生成.pyc文件并将其加载执行
mymod.py --(编译)-> mymod.pyc --(解释执行)->python3
5.2 模块路径的搜索顺序
1 搜索当前路径
2 sys.path提供的路径
3 搜索内置模块
5.3 sys模块
sys.path 模块的搜索路径
sys.platform 操作系统平台信息
sys.argv 命令行参数
sys.exit() 推出程序
5.4 添加模块的加载路径
1 方法1
import sys #sys.path.append("mymod.py所在的绝对路径") sys.path.append("/home/tarena/waid1710/day13/code") import mymod.py #成功
2 方案2
将路径添加在pythonpath环境变量中,该语法为linux与shell想结合的语法
例如:
#$ export PYTHONPATH = $PYTHONPATH:mymod.py的绝对路径 $ export PYTHONPATH=$PYTHONPATH:/home/tarena/waid1710/day13/code
加载后,通过sys.path 可以查看到该路径
PYTHONPATH环境变量
PYTHONPATH环境变量里的值或自动添加到sys.path列表中