在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。
为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Python中,一个.py
文件就称之为一个模块(Module)。
即:
- 包含我们定义的函数以及变量的文件,以“.py”为后缀名。
- 模块可以被其他的程序引用,以使用该模块中的函数或者数据。
模块的优点:
- 1.提高了代码可维护性
- 2.提高了代码的复用性
- 3.可以导入很多功能模块 ( 标准库模块,自定义模块,第三方模块)
- 4.避免了变量名重复
Python中导入模块的方法的简单形式主要有以下三种:
import 模块名
import模块名 as 新名称
from 模块名 import 函数名
区别:
-
import 模块名
和import 模块名 as 新名称
- 会导入整个模块;
- 如果需要使用其中的某一个函数,必须以“模块名.函数名()”的形式调用函数。(通常这种方法,更有利于增强代码的可读性,优先推荐使用该种方法)
import 模块名 as 新名称
用来重新命名导入的模块,以使名称简便,方便使用。
-
from 模块名 import 函数名
- 只是导入模块中的某一函数,而不是导入整个模块。
- 可以直接使用函数名称调用函数,无须再在其前加上“模块名.”。
如果程序语句非常多,我们不建议采用“from 模块名 import 函数名”这种方式,因为采用这种方式调用函数时,我们直接使用函数名称调用函数,当程序语句非常多,我们调用了很多模块后,可能造成函数名重名,引发错误,而“模块名.函数名”的方式则会避免这种情况的发生。
例子:
以Python内建的calendar模块为例,其名称为calendar.py,里面定义了一些日历格式。只要使用import指令导入此模块,就可以使用calendar模块了。
1, 3, 5, 7, 8, 10, 12 —>31天
2月除外,30天
二月:闰年29,平年28
- import …
>>> import calendar #导入模块
>>> print(calendar.month(2019,4)) #调用模块函数
#函数 isleap()判断是否是闰年
April 2019
Mo Tu We Th Fr Sa Su
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
>>>
- import…as…
import calendar as cal
print(cal.month(2019,4)) #调用模块中的month()函数
print(cal.isleap(2019)) #判断是否是闰年
April 2019
Mo Tu We Th Fr Sa Su
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
False
- form…import…
from calendar import month
print(month(2019,4)) #调用模块中的month()函数
print(isleap(2019))
April 2019
Mo Tu We Th Fr Sa Su
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Traceback (most recent call last):
File "E:\python\SublimeProjects\kaoshi2.py", line 305, in <module>
print(isleap(2019))
NameError: name 'isleap' is not defined
注意:
- import 语句的模块顺序
支持python模块开头导入
- python 标准库模块
- python 第三方模块
- 应用程序自定义模块
然后使用一个空行分割这三类模块的导入语句,有助于减少每个模块需要的import的语句数目
限制使用 “ from module import ”
在实践中, 我们认为 “from module import *” 不是良好的编程风格, 因为它"污染"当前名称空间, 而且很可能覆盖当前名称空间中现有的名字; 但如果某个模块有很多要经常访问的变量或者模块的名字很长, 这也不失为一个方便的好办法。
我们只在两种场合下建议使用这样的方法, 一个场合是:目标模块中的属性非常多, 反复键入模块名很不方便, 例如 Tkinter (Python/Tk) 和 NumPy (Numeric Python) 模块, 可能还有socket 模块。另一个场合是在交互解释器下, 因为这样可以减少输入次数。
模块的路径查看:
模块名. __ file __
>>> import calendar
>>> print(calendar.__file__)#双下划线
C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\calendar.py
>>>
自定义模块
自定义是自己写的.py文件
自定义模块名称就是就是我们填写的python程序名
例子:
现在我们创建一个名为a.py的文件:
#程序名称为fibo.py
#斐波那契数列模块
def fib_01(n): #输出最大数小于n的斐波那契数列
i,j = 0,1
while j < n:
print(j , end=" ")
i , j = j , i + j
print()
def fib_02(n): #以列表的形式输出最大数小于n的斐波那契数列
result = []
i , j = 0 , 1
while j < n:
result.append(j)
i , j = j , i + j
return result
#同目录下创建一个新的.py文件
import fibo #导入模块
print(fibo.fib_02(50))
[1, 1, 2, 3, 5, 8, 13, 21, 34]
rload()
内建函数可以重新导入一个已导入的模块
import importlib
importlib.reload(module)
module是你想要重新导入的模块。使用reload0的时候有一些标准。 首先模块必须是全部导入(不是使用from-import),而且它必须被成功导入。另外reload()函数的参数必须是模块自身而不是包含模块名的字符串。也就是说必须类似 reload(sys)而不是reload(sys’)。
模块中的代码在导入时被执行,但只执行-次,以后执行import语句不会再次执行这些代码,只是绑定模块名称。而reload()函数不同。
模块搜索路径
前面我们在导入模块时是要求在fibo.py所在路径下打开命令窗口,为什么呢?
一般情况下, Python解释器在运行程序时,在这之前会自动将程序所在的当前目录添加到sys,path路径列表下,然后,优先搜索当前路径下的模块。在Windows系统中 ,其默认模块搜素路径为Python安装目录及其安装目录下的几个子文件夹,我们可以在python解释器环境下,通过以下方式查看:
>>> import sys #导入sys模块
>>> print(sys.path) #输出当前的模块搜索路径,以列表形式显示
['', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\python36.zip', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\DLLs', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages']
如果我们希望不在fibo.py文件所在目录路径下启动cmd命令窗口就可以导入fibo.py模块,我们可以用:
sys.path.append(AddPath)
临时添加fibo.py文件目录路径
现在,打开cmd
import sys
sys.path.append('E:\\python')
import fibo
print(fibo.fib_01(100))
1 1 2 3 5 8 13 21 34 55 89
包
如果不同的人编写的模块名相同怎么办?为了避免模块名冲突, Python又引入了按目录来组织模块的方法,称为包( Package).,
举个例子,一个name1.py的文件就是一个名字叫namel的模块, -个name2.py 的文件就是一一个名字叫’ name12的模块。
现在,假设我们的name1和name12这两个模块名字与其他模块冲突了,于是我们可以通过包来组织模块,避免冲突。方法是选择一个顶层包名,比如mycode’ ,按照如下目录存放:
mycode
__init__.pt
name1.py
name2.py
引入了包以后,只要]晨的包名不与別人冲突,那所有模快都不会与別人冲突。現在r amety狭的右子就変成了mycode.name1 ,美似的rl name2. py的模快名変成mycode . name2。 请注意,每一个包目录下面都会有-个_ init_ .py的文件 ,这个文件是必须存在的,否则, Python就把这个目录当成普通目录,而不是-一个包。init_ .py 可以是空文件 ,也可以有_Python代码, 因为 init_ .py 本身就是一个模块,而它的模块名就是mycode.
类似的,可以有多级目录,组成多级层次的包结构。比如如下的目录结构:
mycode
web
__init__.py
utils.py
www.py
__init__.py
name1.py
name2.py
文件waw. py的模抉名就是mycede.webw
Notes:自己创建模块时要注意命名,不能和Python自带的模块名称冲突。例如,系统自带了sys模快,自己的模块就不可命名为sys.py .否则无法导入系统自带的sys模块。
Python常用内置模块之time、datetime
(1) time模块
在Python中,表示时间通常有以下几种方式:
- 时间戳(timetamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。如果运行“type(time.time())”,返回的是float类型。
- 格式化时间字符串(Format String)
- 结构化的时间(struct_time):struct_time元组中共有9个元素(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)
为方便理解,现在举例说明:
i.时间戳的理解
import time
print(time.time()) #1555568627.091191
time.sleep(1)
print(time.timi.时间戳的理解
```python
import time
print(time.time()) #1555568627.091191
time.sleep(1)
print(time.time())#1555568628.103416
ii.格式化时间字符串
import time
print(time.strftime("%Y-%m-%d %X")) #2019-04-18 14:26:56
print(time.strftime("%Y-%m-%d %H:%M:%S")) #2019-04-18 14:26:56
iii.结构化的时间e())#1555568628.103416
ii.格式化时间字符串
```python
import time
print(time.strftime("%Y-%m-%d %X")) #2019-04-18 14:26:56
print(time.strftime("%Y-%m-%d %H:%M:%S")) #2019-04-18 14:26:56
iii.结构化的时间
import time
print(time.localtime()) #本地时区
# 输出:time.struct_time(tm_year=2019, tm_mon=4, tm_mday=18, tm_hour=14, tm_min=32, tm_sec=44, tm_wday=3, tm_yday=108, tm_isdst=0)
这里我们可以看出struct_time有9个元素,我们可以通过索引值来引用某个元素
>>> print(time.localtime()[5])
44
>>>
通过以上例子![time](C:\Users\Administrator\Documents\Tencent Files\2026831577\FileRecv\time.png)
时间戳和结构化时间的转化
time.getime(时间戳)
#UTC时间,与英国伦敦时间至
time.localtime(时间戳)
#UTC时间加8小时等于北京时间
结构化时间和时间戳的转化
time.mktime(结构化时间)
demo:
print(time.mktime(time.localtime()))
字符串时间和结构化时间的转化
time.strptime(时间字符串,字符串对应格式)
demo:
print(time.strptime("2019-04-18","%Y-%m-%d"))
time.struct_time(tm_year=2019, tm_mon=4, tm_mday=18, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=108, tm_isdst=-1)
print(time.strptime("04/18/2019","%m/%d/%Y"))
time.struct_time(tm_year=2019, tm_mon=4, tm_mday=18, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=108, tm_isdst=-1)
结构化时间和字符串时间转化**
strftime(fromat[,t])
把一个代表时间的元组或者struct_time(如由time.localtime()和time.gmtime()返回)转化为格式化的时间字符串。如果t未指定,将传入time.localtime()。如果元组中任何一个元素越界,ValueError的错误将会被抛出
例子:
print(time.strftime("%Y-%m-%d %X",time.localtime()))
# 2019-04-18 15:41:25
![time2](C:\Users\Administrator\Documents\Tencent Files\2026831577\FileRecv\time2.png)
结构化时间和字符串时间转化
time.asctime(结构化时间)
如果不传参数,直接返回当前时间的格式化串
例子:
import time
print(time.asctime(time.localtime(1500000000)))
print(time.asctime())
#Fri Jul 14 10:40:00 2017
#Thu Apr 18 16:14:16 2019
时间戳和字符串时间的转化
time.ctime(时间戳)
如果不传入参数,直接返回当前时间的格式化串
例子:
print(time.ctime(1500000000))
print(time.ctime())
#Fri Jul 14 10:40:00 2017
#Thu Apr 18 16:20:13 2019
(2)datetime
datetime模块用于是date和time模块的合集,datetime有两个常量,MAXYEAR和MINYEAR,分别是9999和1
datetime模块定结构化时间和字符串时间转化
time.asctime(结构化时间)
如果不传参数,直接返回当前时间的格式化串
例子:
import time
print(time.asctime(time.localtime(1500000000)))
print(time.asctime())
#Fri Jul 14 10:40:00 2017
#Thu Apr 18 16:14:16 2019
时间戳和字符串时间的转化
time.ctime(时间戳)
如果不传入参数,直接返回当前时间的格式化串
例子:
print(time.ctime(1500000000))
print(time.ctime())
#Fri Jul 14 10:40:00 2017
#Thu Apr 18 16:20:13 2019
(2)datetime
datetime模块用于是date和time模块的合集,datetime有两个常量,MAXYEAR和MINYEAR,分别是9999和1
datetime模块定义了5个类,分别是:
序号 | 类名 | 说明 |
---|---|---|
1 | datetime.date | 表示日期的类 |
2 | datetime.datetime | 表示日期时间的类 |
3 | datetime.time | 表示时间的类 |
4 | datetime.timedelta | 表示时间间隔,即两个时间点的间隔 |
5 | datetime.tzinfo | 时区的相关信息 |
例子:
import time,datetime
print(datetime.datetime.now())#返回当前系统时间
print(datetime.datetime.now().date())#返回当前日期时间的日期部分
print(datetime.datetime.now().time())#返回当前日期时间的时间部分
print(datetime.datetime.now()+datetime.timedelta(-1))#当前时间减1天
print(datetime.datetime.now()+datetime.timedelta(hours=1))#当前时间加1小时
# 2019-04-18 16:29:25.913198
# 2019-04-18
# 16:29:25.913198
# 2019-04-17 16:29:25.913198
# 2019-04-18 17:29:25.913198
义了5个类,分别是:
序号 | 类名 | 说明 |
---|---|---|
1 | datetime.date | 表示日期的类 |
2 | datetime.datetime | 表示日期时间的类 |
3 | datetime.time | 表示时间的类 |
4 | datetime.timedelta | 表示时间间隔,即两个时间点的间隔 |
5 | datetime.tzinfo | 时区的相关信息 |
例子:
import time,datetime
print(datetime.datetime.now())#返回当前系统时间
print(datetime.datetime.now().date())#返回当前日期时间的日期部分
print(datetime.datetime.now().time())#返回当前日期时间的时间部分
print(datetime.datetime.now()+datetime.timedelta(-1))#当前时间减1天
print(datetime.datetime.now()+datetime.timedelta(hours=1))#当前时间加1小时
# 2019-04-18 16:29:25.913198
# 2019-04-18
# 16:29:25.913198
# 2019-04-17 16:29:25.913198
# 2019-04-18 17:29:25.913198