模块:
模块是一系列常用功能的集合体,一个py文件就是一个模块。
一、模块的作用:
1、从文件级别组织程序,方便管理,随着程序的发展,功能越来越多,我们通常将程序分成一个个py文件,这样做程序的结构更清晰,方便管理。这时我们不仅可以把这些文件当做脚本去执行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用。
2、拿来主义,提升开发效率
同样的原理,我们也可以下载别人写好的模块然后导入到自己的项目中使用,这种拿来主义,可以极大地提升我们的开发效率,避免重复造轮子。每个模块都是一个独立的名称空间,定义在这个模块中的函数,把这个模块的名称空间当做全局名称空间,这样我们在编写自己的模块时,就不用担心我们定义在自己模块中全局变量会在被导入时,与使用者的全局变量冲突。
二、导入模块:
import 模块1,模块2,模块3
可以用import以逗号分隔的方式导入多个模块,但是为了代码的可读性不建议这么写,建议分开写。如:
import 模块1
import 模块2
import 模块3
多行导入,易于阅读,易于编辑,易于搜索,易于维护。
import 导入过来的功能都需要使用模块点的方法执行。如下:
import time
print(time.localtime()) # 以模块名time.locatime()的方式调用
import 模块名 as 别名 为模块起别名,如下:
import time as datetime_ # 为模块起别名
print(datetime_.localtime())
import 导入的是整个模块,当我们知道要导入这个模块的某个功能时,我们可以直接导入该模块下的某个功能,而不需要将该模块下的所有功能全部导入。
这时我们可以使用:from 模块名 import 函数名这样就可以导出该模块下的函数了,而不用导入整个模块。如下:
from time import localtime # 导出time模块下的localtime函数
print(localtime()) # 这样就不需要使用模块名.的方式调用函数了
from 模块 import 函数1,函数2,函数3 #也可以导入多个函数,如下:
from time import localtime,strftime,time # 导出time模块下的多个函数
ntime = localtime(time())
print(strftime("%Y-%m-%d %H:%M:%S",ntime))
from 模块名 import 函数名 as 别名:函数名 as 别名 可以更改多个。
from time import localtime as localtime_,time as time_ # 起别名
print(localtime_(time_()))
from 模块名 import * 导出模块下所有函数,不推荐使用。
from time import * # 导出time模块下的所有函数
print(localtime(time()))
小结:以time模块为例。
1、import time 可以导出time模块下的所有函数,在使用这些函数时需要使用 time.函数名 的方式来调用函数。
from time import * 导出time模块下的所有函数,直接使用函数名的方式来调用,不使用模块名.函数名的方式调用。
2、import 模块1,模块2,模块3 虽然可以这样写,但是不建议这么写,这么写可读性不是很好,也不利于修改和查找。同理
from 模块名 import 函数名1,函数名2 这么写也是不可取的。
3、import 模块名 as 别名 给模块起别名
from 模块名 import 函数名 as 别名 给函数起别名
4、import 模块名 as 别名,模块名2 as 别名 可以这么写
from 模块名 import 函数名 别名,函数名 as 别名 虽然可以这么写但是我们尽量不要这么写。
扩展知识:
__all__ = ['可以被导入的内容'] 用这种方式强制from 模块名 import *只导出指定的内容。
如下图所示:__all__ = ["fun"] 只允许import * 导出fun()函数,而不允许调用fun_2()函数。
if __name__ == '__main__'的意思是,当.py文件被直接运行时,if __name__ == '__main__'之下的代码块将被运行。
当.py文件以模块形式被导入时,if __name__ == '__main__'之下的代码块不被运行。多用于测试模块内函数是否运行正确。
以上图可以看出我们导入模块后,fun_2()被调用了,但if __name__ == '__main__'的代码没有被执行。所以,以后我们在写模块时,如果要测试哪个函数最好是在
if __name__ == '__main__'里进行,以免测试后忘记注释或删除调用,导致在引用该模块时执行里面的函数。
三、模块的搜索顺序:
内存中已经加载的模块 - > 内置模块 - > sys.path路径中包含的模块。
下面是打印当前python环境下的路径:
import sys
print(sys.path) # 打印当前Python环境变量
如果要添加其它盘符中的模块,需要把模块的路径加载到Python的环境中去。
import sys
sys.path.insert(0,r"模块路径") # 将一个模块路径插入到当前Python环境变量
print(sys.path) # 打印当前python环境变量
四、编译Python文件
为了提高加载模块的速度,提高的是加载速度而绝非运行速度。python解释器会在__pycache__目录中下缓存每个模块编译后的版本,格式为:module.version.pyc。如下图所示
这种命名规范保证了编译后的结果多版本共存,Python检查源文件的修改时间与编译的版本进行对比,如果过期就需要重新编译。这是完全自动的过程。并且编译的模块是平台独立的,所以相同的库可以在不同的架构的系统之间共享,即pyc是一种跨平台的字节码,类似于JAVA或.net。是由python虚拟机来执行的,但是pyc的内容跟python的版本相关,不同的版本编译后的pyc文件不同,2.5编译的pyc文件不能到3.5上执行,并且pyc文件是可以反编译的,因而它的出现仅仅是用来提升模块的加载速度的,不是用来加密的。
小结:
1、模块名区分大小写,fun.py与FUN.py代表的是两个模块。
2、在速度上从.pyc文件中读指令来执行不会比从.py文件中读指令执行更快,只有在模块被加载时,.pyc文件才是更快的 。
3、只有使用import语句时才将文件自动编译为.pyc文件,在命令行或标准输入中指定运行脚本则不会生成这类文件。
五、time模块
在计算机中时间共有三种形式:
1、时间戳:通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。
2、格式化字符串时间(FORMat String):人类能读懂的时间如:2018-1-1 14:10
3、结构化时间:元组(struct_time) struct_time元组共有9个元素(年,月,日,时,分,秒,一年中第几周,一年中第几天等)。如下图所示:
tm_year(年) |
如:2018(年) |
tm_mon(月) |
1 - 12 |
tm_mday(日) |
1 - 31 |
tm_hour(时) |
0 - 23 |
tm_min(分) |
0 - 59 |
tm_sec(秒) |
0 - 61 |
tm_wday(周) |
0 - 6(周一是0) |
tm_yday(一年中的第几天) |
1 - 366(天) |
tm_isdst(是否是夏令时) |
0不是,1是,-1未知 |
python中日期,时间格式化:
Directive |
Meaning |
%a |
简写周(如周一(Monday):简写成Mon) |
%A |
周的全写(如周一(Monday):Monday) |
%b |
月的简写(如2月(February):简写Feb) |
%B |
月的全写(如2月(February):February) |
%c |
默认显示(如当前日期:Mon Feb 18 15:03:38 2019). |
%d |
一个月的第几天(1 - 31) |
%H |
时 (0,24) |
%I |
时(1,12) |
%j |
一年中的第几天(1,366) |
%m |
月(1,12) |
%M |
分(0,59) |
%p |
对应AM/PM |
%S |
秒(0,61) |
%U |
一年中第几周 (0,53) |
%w |
一周的第几天 (0,6)0是周一 |
%W |
一年中第几周 (0,53)与%U类似 |
%x |
默认年月日如:02/18/19(月/日/年) |
%X |
默认时分秒如:15:23:46(时:分:秒) |
%y |
去掉世纪年份(0,99)如:2019显示19 |
%Y |
完整的年份 |
%z |
打印时区 |
%Z |
时区(如果不存在打印空) |
%% |
打印字符% |
time模块的时间转换:
我们知道了time模块时间有三种表现形式:时间戳、结构化时间、字符串时间。我们可以根据下面这张图进行转换。
时间戳到字符串时间的转换:
import time
nTime = time.time() # 获取时间戳
structTime = time.localtime(nTime) # 将时间戳转换结构化时间
strTime = time.strftime("%Y-%m-%d %H:%M:%S",structTime) # 将结构化时间转换成字符串时间
print("字符串时间:",strTime) # 打印字符串时间
# 打印内容如下
字符串时间: 2019-02-18 15:40:17
字符串时间回退到时间戳:
import time
strTime = "2019-02-18 15:40:17"
print("字符串时间:",strTime)
struct_Time = time.strptime(strTime,"%Y-%m-%d %H:%M:%S") # 将字符串时间转换成结构化时间
nTime = time.mktime(struct_Time) # 将结构化时间转换成时间戳
print("时间戳:",nTime)
# 打印内容如下
字符串时间: 2019-02-18 15:40:17
时间戳: 1550475617.0
六、datetime模块
打印当前时间:
from datetime import datetime
print(datetime.now(),type(datetime.now())) # 获取当前时间
# 打印内容如下
2019-02-18 15:47:38.337810 <class 'datetime.datetime'>
指定日期,时间并创建一个datetime的类:
from datetime import datetime
dt = datetime(2019,2,18,15,50,0) # 指定日期,时间
print(type(dt),dt)
# 打印内容如下
<class 'datetime.datetime'> 2019-02-18 15:50:00
datetime类转换时间戳:
from datetime import datetime
dt = datetime.now() # 获取时间类
new_timestamp = dt.timestamp() # 将时间类转换成时间戳
print(new_timestamp)
# 打印内容如下
1550476362.400201
将时间戳转换成字符串时间:
from datetime import datetime
nTime = datetime.timestamp(datetime.now()) # 时间戳
print(datetime.fromtimestamp(nTime)) # 将时间戳转换成类
# 打印内容如下
2019-02-18 15:53:50.835115
将str转换成datetime:
from datetime import datetime
nTime = datetime.strptime("2019-1-15","%Y-%m-%d") # 将字符串时间转换成时间类
print(type(nTime),nTime)
# 打印内容如下
<class 'datetime.datetime'> 2019-01-15 00:00:00
将datetime转换成str:
from datetime import datetime
nTime = datetime.now() # 获取时间类
strTime = datetime.strftime(nTime,"%Y-%m-%d %H:%M:%S") # 将时间类转换成字符串
print(type(strTime),strTime)
# 打印时间如下
<class 'str'> 2019-02-18 15:56:13
datetime的加减法:需要使用timedelta类。
from datetime import datetime,timedelta
nTime = datetime.now() # 系统当前时间
print("当前时间:",nTime)
otherTime = nTime - timedelta(days=1) # 当前时间减去1天
print("减去一天后的时间:",otherTime)
# 打印内容如下
当前时间: 2019-02-18 15:57:48.071684
减去一天后的时间: 2019-02-17 15:57:48.071684
timedelta可选参数,就不一一举例了,有兴趣的朋友可以自己尝试。
days: float = ...,
seconds: float = ...,
microseconds: float = ...,
milliseconds: float = ...,
minutes: float = ...,
hours: float = ...,
weeks: float = ..., *,
fold: int = ..
0