模块(module)
开发过程中,程序代码会越来越多,如果直接放在一个文件里,代码会越来越长。—> 代码不易维护
为了编写方便维护代码,可以把不同功能的代码分组,保存在不同的文件里。这样,每个文件包含的代码量就会比较少,更方便维护。
再Python中,一个.py文件就可以称之为一个模块。
即:
- 包含相应功能的函数以及变量,py则以“.py”为后缀名;
- 模块可以为其他的程序引用,以使用该模块所对应的函数或者变量。
使用模块的优点:
- 提高代码的维护性
- 提高代码的复用性
- 可以导入很多功能的模块
- 标准库模块
- 第三方模块
- 自定义模块
- 避免变量名重复(作用域)
Python中导入模块的常用方式
import 模块名称
import 模块名称 as 新名称
from 模块名称 import 函数名
区别:
- import 模块名称 和 import 模块名称 as 新名称
- 会导入整个模块
- 如果我们需要使用某个函数,必须以“模块名称,函数名()”的形式来调用相应的函数。(这种方法可以更有利于代码的可读性,也是优先推荐的方法)
- import 模块名称 as 新名称,重新命名导入的模块,通常使用模块名称简洁,方便使用。
- from 模块名称 import 函数名
- 只导入了某一函数,而不是一整个模块
- 可以直接函数名称去调用函数,而无需在函数名称前加模块名称
- 如果我们的程序语句很多,不建议采用该种方法(原因:调用很多模块后,可能造成函数名重名,引发错误。)
import …
import … as …
from … import 函数
注意:
import语句的对应模块顺序(PEP)(放在程序最上方,三者同时存在时的放置顺序)
- Python标准模块(random、string、math、calendar)
- 第三方
- 自定义
自定义模块
#例:自定义module_test模块
def fib_01(n):
i, j = 0, 1
while j < n:
print(j, end=" ")
i, j = j, i + j
print()
fib_01(100)
def fib_02(n):
res = []
i, j = 0, 1
while j < n:
res.append(j)
i, j = j, i + j
return res
print(fib_02(100))
os模块
os模块是Python标准库中用于访问操作系统功能的模块。
使用OS模块提供的接口,能够实现跨平台访问。
最常见的操作:
- 目录的操作
- 判断
1、系统操作
- os.sep:用于查看系统路径的分隔符;
- Windows —> ‘\’
- ubuntu —> ‘/’
- os.name:显示我们正在使用的平台
- Windows —> ’nt‘
- Linux/Unix —> ‘posix’
- os.getenv() —> 读取环境变量(environment)
- os.getcwb() —> 获取当前路径
2、目录操作 — 增删改查(direction)
-
os.listdir():返回指定目录下的所有文件和(查)
- 未指定路径,当前路径下
- 指定路径下
>>> os.listdir() ['.anaconda', '.android', '.conda', '.designer', '.ipython', '.keras', '.matplotlib', '.oracle_jre_usage', '.PyCharm2018.1', '.spyder-py3', '3D Objects', 'AppData', 'Application Data', 'Contacts', 'Cookies', 'Desktop', 'Documents', 'Downloads', 'Favorites', 'IntelGraphicsProfiles', 'Links', 'Local Settings', 'MicrosoftEdgeBackups', 'Music', 'My Documents', 'NetHood', 'NTUSER.DAT', 'ntuser.dat.LOG1', 'ntuser.dat.LOG2', 'NTUSER.DAT{34b388ff-30db-11e8-adb2-b4f8a0758d5c}.TxR.0.regtrans-ms', 'NTUSER.DAT{34b388ff-30db-11e8-adb2-b4f8a0758d5c}.TxR.1.regtrans-ms', 'NTUSER.DAT{34b388ff-30db-11e8-adb2-b4f8a0758d5c}.TxR.2.regtrans-ms', 'NTUSER.DAT{34b388ff-30db-11e8-adb2-b4f8a0758d5c}.TxR.blf', 'NTUSER.DAT{34b38900-30db-11e8-adb2-b4f8a0758d5c}.TM.blf', 'NTUSER.DAT{34b38900-30db-11e8-adb2-b4f8a0758d5c}.TMContainer00000000000000000001.regtrans-ms', 'NTUSER.DAT{34b38900-30db-11e8-adb2-b4f8a0758d5c}.TMContainer00000000000000000002.regtrans-ms', 'ntuser.ini', 'ntuser.pol', 'Pictures', 'PrintHood', 'Recent', 'Saved Games', 'Searches', 'SendTo', 'Templates', 'Videos', '「开始」菜单'] >>> dirs = "D:\python_test" >>> os.listdir(dirs) ['.idea', 'learn', 'py', 'test1']
-
目录的创建(增)
- os.mkdir(path):创建目录,但仅能创建一级目录
- os.makedirs(path):创建目录,可创建多级目录
>>> os.mkdir("os_test") >>> >>> os.makedirs("main_file/sub_file")
-
目录/文件删除(删)
- os.rmdir(path):删除空目录(一级)
- os.removedirs(path):删除空目录(多级)
- os.remove(path):删除文件,必须是文件
-
更改路径(改)
- os.chdir(path):change direction # 将当前工作目录更改到指定的工作目录
- os.rename(old_name,new_name):修改目录名称
>>> os.getcwd() 'C:\\Users\\Administrator' >>> os.chdir("..") >>> os.getcwd() 'C:\\Users' >>> os.rename('date.txt','date.md')
判断文件
- os.path.exists(path):判断文件或者目录是否存在,存在,True;不存在,False(有后缀名表示文件,无后缀表示文件夹)
- os.path,isfile(path):判断是否为文件,是,True;否,False
- os.path.isdir(path):判断是否为目录,是,True;否,False
>>> os.path.isdir("date")
True
>>> os.path.isdir("date.md")
False
>>> os.path.isfile("file.txt")
True
>>> os.path.isfile("file")
False
拓展:
- os.path.dirname(path):返回文件路径;
- os.path.basename(path):返回文件名称;
- os.path.getsize(path):返回文件的大小
- os.path.abspath(path):返回文件的绝对路径
- os.path.join(path,name):连接目录与(文件名或目录),类似于字符串的拼接
- os.path.split(path):将path的目录和文件名称分割开并返回元组
查看文件的时间(从1970.1.1零点开始算)
-
os.path.getmtime(path):返回文件或者目录的最后修改的时间,结果为秒数 —> modify
-
os.path.getatime(path):返回文件或者目录的最后访问的时间,结果为秒数
-
os.path.getctime(path):返回文件或者目录的创建时间,结果为秒数
im_g = os.path.getmtime('test1.py')
tm = os.path.getctime('test1.py')
im = os.path.getatime('test1.py')
print(time.strftime('%Y-%m-%d %X', time.localtime(im_g)))
print(time.strftime('%Y-%m-%d %X', time.localtime(tm)))
print(time.strftime('%Y-%m-%d %X', time.localtime(im)))
#
2019-07-20 13:01:59
2019-07-16 09:28:07
2019-07-20 13:12:44
获取文件目录
- os.walk(path):方法用于通过在目录树种游走输出在目录中的文件名,向上或者向 下
包(module and package)
包:包是通过使用’ . 模块名’来组织Python模块名称空间的方式。
—> 具体而言,包就是一个包含 __init__.py
文件的文件夹
- 目的:用文件夹将文件/模块组织起来。
注意:
py3,即使没有
__init__.py
也可以使用py2,如果没有肯定报错
创建包的目的不是为了运行还是为了被导入使用。
包的本质依然还是模块。
- 使用时,import导入,导入带点的,点的最左边一定是包名。
- import导入文件时,产生名称空间的名字源于文件,import包,名称空间同样源于文件(包),
__init__.py
,导入包的本质就是导入它。
➜ school tree
.
├── api
│ ├── __init__.py
│ ├── students.py
│ └── versions.py
├── cmd
│ ├── __init__.py
│ └── manage.py
├── db
│ ├── __init__.py
│ └── models.py
└── __init__.py
#例:
import school.db.models
school.db.models.register_models('MySQL')
# import school
#
# school.cmd.manage.main() # 报错(单独导入包的时候,不会导入该包中所包含的所有模块)
from school.cmd import manage # import后面一定不能带 . ,不然会报错
manage.main()
from school.cmd.manage import main
main()
'''
from models.py MySQL
from manage.py
from manage.py
'''
若要使报错的变正确我们应该在school文件夹下的__init__.py
里打印from . import cmd
再在cmd文件夹下的__init__.py
里打印from . import manage
之后在test.py里打印
import school
school.cmd.manage.main()
即可运行:from manage.py,结果同上
from … import … 时,import后导入的模块,不能有点(.),否则报错
字符编码
Python主要时识别文件内容,而不关心拓展名 —> 解释器
字符 ----> (机器翻译)—> 二进制
字符如何对应特定数字的标准,这个标准就是字符编码。
ASCII
GBK
Unicode
UTF-8(Unicode Transformation Format)
- 对于英文字符来说,1Bytes
- 对中文字符来说,3Bytes
- 对其他偏僻的字符,就可能有更多的bytes
对于内存而言 —> Unicode
utf-8 — decode — Unicode
time 模块
import time
time.sleep([n]) # 休眠n秒
time.time() # 获取当前时间戳,
在Python中,表示时间通常有3种方式:
- 时间戳(timetamp):表示的是从1970.01.01 00:00:00开始按秒计算的一个偏移量。
- 格式化的时间字符串(format string)
2019-7-26 08:47:40
- 结构化的时间字符串(struct_time)—> 元组,9个元素,(年月日时分秒,一年的第几周,一年的第几天,夏令时)
python中时间日期格式化符号:
表示 | 描述 |
---|---|
%y | 两位数的年份表示(00-99) |
%Y | 四位数的年份表示(000-9999) |
%m | 月份(01-12) |
%d | 月内中的一天(0-31) |
%H | 24小时制小时数(0-23) |
%I | 12小时制小时数(01-12) |
%M | 分钟数(00=59) |
%S | 秒(00-59) |
%a | 本地简化星期名称 |
%A | 本地完整星期名称 |
%b | 本地简化的月份名称 |
%B | 本地完整的月份名称 |
%c | 本地相应的日期表示和时间表示 |
%j | 年内的一天(001-366) |
%p | 本地A.M.或P.M.的等价符 |
%U | 一年中的星期数(00-53)星期天为星期的开始 |
%w | 星期(0-6),星期天为星期的开始 |
%W | 一年中的星期数(00-53)星期一为星期的开始 |
%x | 本地相应的日期表示 |
%X | 本地相应的时间表示 |
%Z | 当前时区的名称 |
%% | %号本身 |
time 模块的常用方法
方法 | 描述 |
---|---|
time.localtime([sec]) | 将一个时间戳转化为一个当前时区的struct_time(若未提供参数,当前时间) |
time.gmtime([sec]) | 和localtime()类似,不同的是,其是将一个时间戳转换为UTC时区(0时区)的struct_time |
time.time | 返回当前时间戳 |
time.mktime(t) | 将time.struct_time转化为时间戳 |
time.sleep(sec) | 线程推迟指定的时间运行,单位(s) |
time.asctime([t]) | 把表时间的元组或struct_time表示为:”Sun July 26 09:06:35 2019“;如果未传参数,默认为time.localtime() |
time.ctime([t]) | 把一个时间戳转化为time.asctime()的形式。如果未传参数,默认time.time() |
time.strtime(format[, t]) | 把一个代表时间的元组/struct_time(localtime()和gmtime()转化为格式化的字符串,未传参数,默认为time.localtime()) |
time.strptime() | 将结构化字符串转化为struct_time形式 |
- 时间戳,机器识别
- 字符串,人类看的
- 结构化时间,对时间操作
时间戳和结构化时间的转化
- time.gmtime(now)
- time.localtime(now)
>>> now = time.time()
>>> time.gmtime(now) # UTC时间,0时区
time.struct_time(tm_year=2019, tm_mon=7, tm_mday=26, tm_hour=1, tm_min=17, tm_sec=20, tm_wday=4, tm_yday=207, tm_isdst=0)
>>>
>>> time.localtime(now) # 当地时间,以北京所在时区为准
time.struct_time(tm_year=2019, tm_mon=7, tm_mday=26, tm_hour=9, tm_min=17, tm_sec=20, tm_wday=4, tm_yday=207, tm_isdst=0)
>>>
结构化时间和时间戳的转化
- time.mktime(结构化时间)
>>> tp_struct = time.localtime()
>>> time.mktime(tp_struct)
1564104175.0
>>> time.time()
1564104188.0654154
>>>
结构化时间到字符串时间的转化
- time_strftime(format[, t])
>>> tp_struct = time.localtime()
>>> time.strftime("%Y-%m-%d %X", tp_struct)
'2019-07-26 09:27:36'
>>>
字符串时间到结构化时间的转化
- time.strptime(时间字符串,字符串对应格式)
>>> time.strptime("2019-7-26", "%Y-%m-%d")
time.struct_time(tm_year=2019, tm_mon=7, tm_mday=26, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=207, tm_isdst=-1)
>>>
>>> time.strptime("2019/7/26", "%Y/%m/%d")
time.struct_time(tm_year=2019, tm_mon=7, tm_mday=26, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=207, tm_isdst=-1)
>>>
结构化时间和字符串时间的转化(国际化时间字符串)
- time.asctime(结构化时间)
>>> tp_struct = time.localtime()
>>> time.asctime(tp_struct)
'Fri Jul 26 09:48:38 2019'
>>>
>>> time.asctime()
'Fri Jul 26 09:49:58 2019'
>>>
时间戳和字符串的转化(国际化)
>>> time.asctime()
'Fri Jul 26 09:49:58 2019'
>>> time.ctime(time.time())
'Fri Jul 26 09:51:37 2019'
>>> time.ctime()
'Fri Jul 26 09:51:55 2019'
>>> time.ctime(1500000000)
'Fri Jul 14 10:40:00 2017'
>>>
datetime 模块
相比time来说,datetime模块接口更直观,更容易调用
方法(类) | 描述 |
---|---|
datetime.date | 表示日期(类),常用属性:year,month,day |
datetime.time | 表示时间(类),常用属性:hour,minute,second,microsecond |
datetime.datetime | 表示日期 |
datetime.timedelta | 表示时间间隔 |
datetime.tzinfo | 与时区有关的信息 |
>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2019, 7, 26, 10, 1, 52, 336061)
>>> print(datetime.datetime.now())
2019-07-26 10:02:12.213297
>>>
>>> print(datetime.datetime.now().date())
2019-07-26
print(datetime.datetime.now()+datetime.timedelta(-1)) # 当前时间减一天
print(datetime.datetime.now()+datetime.timedelta(hours = 1)) # 当前时间加一小时
sys模块
sys模块是与Python解释器交互的一个接口
import sys # 显示本地字节序的指示符。
print(sys.byteorder) # 显示Python解释器有关的版权信息
print(sys.copyright) # 显示Python解释器在磁盘上的存储路径
print(sys.executable) # 显示当前系统上保存文件所用的字符集。
print(sys.getfilesystemencoding()) # 显示Python整数支持的
print(sys.platform)
print(sys.version)
处理命令行参数
在解释器启动后,argv列表包含了传递脚本的所有参数,列表的第一个元素是脚本自身的名称。
>>> import sys
>>> sys.version
'3.6.7 (v3.6.7:6ec5cf24b7, Oct 20 2018, 13:35:33) [MSC v.1900 64 bit (AMD64)]'
>>> sys.path
['', 'D:\\python\\python36.zip', 'D:\\python\\DLLs', 'D:\\python\\lib', 'D:\\python', 'D:\\python\\lib\\site-packages', 'D:\\python\\lib\\site-packages\\setuptools-28.8.0-py3.6.egg', 'D:\\python\\lib\\site-packages\\pip-9.0.1-py3.6.egg']
>>>
序列化模块
序列化概念:
将一个对象从内存中转换为可存储(字符串类型)或者可传输(bytes)类型的过程。
Python中叫pickling。
使用序列化的好处:
- 持久化数据类型
- 跨平台交互使用
- 使程序更易维护
json
json格式在各个语言中都可以通用序列化格式。在json中,所有的字符串必须为” “。
Json类型 | Python类型 |
---|---|
{} | dict |
[] | list |
“string” | str |
1234.56 | int/float |
true/false | True/False |
null | None |
json 优缺点:
- 优点:所有的数据类型是各语言通用的。
- 缺点:
- json只支持比较少的数据类型
- 对数据类型的约束十分严格
- 字典中的key必须是字符串
- json只支持列表,字典,数值,字符串以及布尔值
查看json的方法和属性
>>> import json
>>> dir(json)
['JSONDecodeError', 'JSONDecoder', 'JSONEncoder', '__all__', '__author__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', '_default_decoder', '_default_encoder', 'codecs', 'decoder', 'detect_encoding', 'dump', 'dumps', 'encoder', 'load', 'loads', 'scanner']
>>>
四个功能:
序列化
-
dump
-
dumps
>>> import json # 序列化 >>> dic = {"name":"City College","age":20,"type":"University"} >>> sr_dic = json.dumps(dic) # 序列化,将字典转化为一个字符串 >>> type(sr_dic) <class 'str'> >>> print(sr_dic) {"name": "City College", "age": 20, "type": "University"} >>> dic {'name': 'City College', 'age': 20, 'type': 'University'} >>> sr_dic '{"name": "City College", "age": 20, "type": "University"}' >>> >>> dic = {"seq":(1,2,3)} >>> sr_dic = json.dumps(dic) >>> sr_dic '{"seq": [1, 2, 3]}' >>> >>> dic = {"name":"City College","age":20,"type":"University",2:6} >>> sr_dic = json.dumps(dic) >>> sr_dic '{"name": "City College", "age": 20, "type": "University", "2": 6}' >>>
反序列化
-
load
-
loads
# 反序列化 >>> dic_2 = json.loads(sr_dic) >>> type(dic_2) <class 'dict'> >>> dic_2 {'name': 'City College', 'age': 20, 'type': 'University', '2': 6} >>> # 如果是元组,序列化时强转为列表;若元组作为字典的键,序列化时报错。
如果把数据类型直接序列化写入文件中,可以用dump和load方法。
pickle
只用于Python
内存中结构化的数据 <—> 格式pickle <—> bytes类型 <—> 保存在文件或基于网络传输
pickle优缺点:
- 优点:
- 支持Python中的几乎所有类型
- pickle会把数据类型序列化为bytes类型
- 缺点:
- 只支持Python
模块提供四个功能:
- 序列化
- dumps
- dump
- 反序列化
- loads
- load