一、包
- 说明:包【package】是一种管理 Python 模块命名空间的形式,采用"点模块名称";就好像使用模块的时候,你不用担心不同模块之间的全局变量相互影响一样,采用点模块名称这种形式也不用担心不同库之间的模块重名的情况。
- 解释:
- package本质是一个文件夹【目录】,但是特殊之处在于:该文件夹下有一个文件__init__.py,代表初始化,但是前期空的,后期在项目开发中,会在其中书写一些项目的配置信息
- 注意:实际上,一个py文件就是一个模块,一个模块名包括包名,如:import aaa.file ,aaa表示包名或者目录名。file是文件名,二者同时组成了一个模块名
- 注意:导包导的是一个模块,模块当中包含包名和py文件名!
- 模块的优点【面试题】:
- 提高代码的可维护性
- 提高了代码的复用度,当一个模块书写完毕,可以被多个地方引用
- 引用其他的模块
- 避免函数名和变量名的命名冲突
- 包的本质就是归纳文件
- 建包:
- 方法一:先建文件夹,然后在文件夹中建一个__init__.py命名的py文件。
- 方法二:直接在pycharm当中新建Python Package,系统会自动在其中创建__init__.py文件。
'''
模块的使用
说明:以下实验当中用到两个包,且与该代码所在py文件属于同一级根目录,做如下介绍
第一个:package_test,其中定义有一个m1.py文件,m1当中内容如下:
n = 0
s01 = 'package_test'
def fun_pt():
print('package_test')
第二个:package_test01,其中定义有一个m1.py文件,m1当中内容如下:
n = 1
s01 = 'package_test01'
def fun_pt01():
print('package_test01')
'''
#1、import导包方法
#a:分别导入
#import bao1.py
#import bao2.py
#b:一起导入
#import bao1,bao2 (注意包都是以py为后缀名)
# 访问模块中的变量和调用函数
# import package_test.m1,package_test01.m1
# print(package_test.m1.n) #0
# print(package_test01.m1.n) #1
#
# print(package_test.m1.s01) #package_test
# print(package_test01.m1.s01) #package_test01
#
# package_test.m1.fun_pt() #package_test
# package_test01.m1.fun_pt01() #package_test01
'''
用import 模块名 方法导包:
好处:可以区分不同模块中同名的变量,函数或类
缺点:一个模块中的变量或函数较多,如果都需要访问,每次访问需要声明模块的路径(对于该缺点,可以通过import as给模块取别名的方法解决)
'''
#1.1、import ~ as ~导包方式
#import 模块名(后缀是.py) as 别名
# import package_test.m1 as pt
# import package_test01.m1 as pt1
#
# pt.fun_pt() #package_test
# pt1.fun_pt01() #package_test01
#2、from 包1.包2....py文件名 import 变量名/函数名/类名 导包方法
from package_test.m1 import fun_pt,n
from package_test01.m1 import fun_pt01,n
print(n) #1 (这里为什么是package_test01当中的1,而不是package_test中的0:因为同名后面导包覆盖前面导包)
fun_pt() #package_test
fun_pt01() #package_test01
#注意:from 包1.包2....py文件名 import *:从指定模块中导入所有内容
"""
好处:当访问变量或调用函数的时候,无需多次声明模块的路径
缺点:如果当多个模块中出现同名的变量,函数或者类,当访问的时候,则会出现覆盖问题,后导入的会覆盖掉之前导入的
"""
#dir():获取一个对象的所有内容,包括变量和函数,类
'''
作用:可以当做一个工具使用,可以查看一个模块,变量,对象中的所有的内容
'''
import random,package_test.m1
print(dir(random)) #是个列表,列表中打印所有random模块当中的变量和函数,类
print(dir(package_test.m1)) #是个列表,列表中打印所有package_test.m1模块当中的变量和函数,类
print(dir("afaf")) #是个列表,列表中打印所有"afaf"对象相关的变量和类
#__name__:获取当前正在执行的模块的名称
# 如果是当前文件运行,则__name__的值为__main__,如果是其他文件在运行,当前文件是被导入的,则__name__的值为模块名
'''
修改package_test.m1.py当中内容
n = 0
s01 = 'package_test'
def fun_pt():
print('package_test')
if __name__ == "__main__":
print('__main__')
else:
print('!')
'''
package_test.m1.fun_pt() #(会首先在导入模块的时候打印“!”)在最后打印package_test
# 使用场景:如果封装一个模块,在模块本身中如果要进行函数代码测试,则可以将测试代码书写到if __name__ == "__main__":
# 当在其他文件中导入该模块时,只需要调用需要的内容即可,if中的代码不会被执行
二、自定义模块
- 概念:目前代码比较少,写在一个文件中还体现不出什么缺点,但是随着代码量越来越多,代码就越来越难以维护。为了解决难以维护的问题,我们把很多相似功能的函数进行分组,分别放到不同的文件中。这样每个文件所包含的内容相对较少,而且对于每一个文件的大致功能可用文件名来体现。很多编程语言都是这么来组织代码结构。
注意:其实一个.py文件就是一个模块
三、系统模块
-
说明:
-
1、time模块
- Python 程序能用很多方式处理日期和时间,转换日期格式是一个常见的功能。Python 提供了一个 time 和 calendar 模块可以用于格式化日期和时间。时间间隔是以秒为单位的浮点小数。每个时间戳都以自从1970年1月1日午夜(历元)经过了多长时间来表示。Python 的 time 模块下有很多函数可以转换常见日期格式。
- 1>名词解释
UTC,格林威治天文时间,世界标准时间,在中国为UTC+8小时
DST:夏令时,表示时间的显示格式 - 2>时间的表示形式【掌握】
a.时间戳:以整型或浮点型表示的是一个以秒为单位的时间间隔,这个时间的基础值是1970.1.1的零点开始算起。
b.时间元组格式:采用Python的数据结构表示,这个元组有9个整型内容,分别表示不同的含义
- c.格式化的时间字符串
-
2、datetime模块:datetime模块是在time模块的基础上进行了二次封装
-
3、calendar模块:calendar /ˈkælɪndə®/ n. 日历;日程表
-
4、string模块:string模块是关于字符串的模块
-
5、os模块:os模块中包含普通的操作系统功能,提供了非常丰富的方法用来处理文件和目录
#1、time模块
from time import *
print(time()) #1666780887.8564095 (获取当前时间的时间戳)
print(gmtime()) #time.struct_time(tm_year=2022, tm_mon=10, tm_mday=26, tm_hour=10, tm_min=43, tm_sec=21, tm_wday=2, tm_yday=299, tm_isdst=0) (获取当前时间的UTC,元组形式)
print(localtime()) #time.struct_time(tm_year=2022, tm_mon=10, tm_mday=26, tm_hour=18, tm_min=45, tm_sec=21, tm_wday=2, tm_yday=299, tm_isdst=0)(获取当地时间,元组形式)
t = localtime()
t1 = mktime(t) #将时间的元组形式转换为时间戳
print(t1) #1666781244.0
print(ctime(t1),type(ctime(t1))) #Wed Oct 26 18:49:29 2022 <class 'str'> (将时间戳转化为时间字符串,格式为默认格式)
print(asctime(t),type(asctime(t))) #Wed Oct 26 18:52:37 2022 <class 'str'> (将时间的元组形式转换为时间的字符串)
#strftime将时间的元组形式转换为时间的字符串,可以自定义格式(★★★★★)
# %Y:year %m:month %d:day %H:hour %M:minutes %S:seconds
t2 = strftime("%Y.%m.%d %H-%M-%S",t)
print(t2) #2022.10.26 19-03-34
#strptime():将时间的字符串形式转换为时间元组形式,也可以理解为解析时间字符串(★★★★★)
t3 = strptime('2022、10/26 19-03-34','%Y、%m/%d %H-%M-%S')
print(t3) #time.struct_time(tm_year=2022, tm_mon=10, tm_mday=26, tm_hour=19, tm_min=3, tm_sec=34, tm_wday=2, tm_yday=299, tm_isdst=-1)
#sleep():休眠,让程序进入阻塞状态,指定时间达到之后,会自动解除阻塞,程序会继续向下执行(★★★★★)
#应用场景:使用在进程和线程中较多
# print('star')
# sleep(5) #其中输入的时间单位为秒
# print('end')
#=====================================================================================================================
#2、datetime模块
import datetime
"""
date:日期,包含年月日
time:时间,包含时分秒
datetime:日期和时间,包含年月日时分秒
tzinfo:时区
"""
#获取当前时间(★★★★★)
d1 = datetime.datetime.now()
print(d1) # 2022-10-26 19:11:28.458505 (注意这里不是str类型)
print(type(d1)) #<class 'datetime.datetime'> (这里是时间格式)
#将时间转换为字符串【时间字符串的格式化】(和time模块当中调用方法不一样)
d2 = datetime.datetime.now() #先获取当前时间
time_str1 = d2.strftime("%Y.%m.%d %H:%M:%S")
print(time_str1) #2022.10.26 19:15:01
print(type(time_str1)) #<class 'str'>
#将格式化字符串转换为时间格式
d3 = datetime.datetime.strptime("2022-10-26 19:15:01","%Y-%m-%d %H:%M:%S")
print(d3) #2022-10-26 19:15:01
print(type(d3)) #<class 'datetime.datetime'>
#两个时间对象之间可以进行减法运算(★★★★★)
date1 = datetime.datetime(2020,10,1,14,15,30,100) #先将容器内容转化为时间格式
date2 = datetime.datetime(2021,11,3,13,30,31,100)
d4 = date2 - date1
print(d4) #397 days, 23:15:01
print(d4.days) #397 property属性
print(d4.seconds) #83701
#=====================================================================================================================
#3、calendar模块(日利率模块)
import calendar
# 1.判断是否是闰年 (★★★★★)
print(calendar.isleap(2020)) #True
# 2.获取指定年指定月的万年历
print(calendar.month(2020,10))
# 3.获取指定年的万年历
print(calendar.calendar(2020))
# 4.获取指定日期的星期,取值范围为:0~6
print(calendar.weekday(2022,10,26)) #2 该日期为星期三
# 5.获取指定年份之间闰年的个数
print(calendar.leapdays(2000,2021))
print(dir(calendar)) #打印calendar当中用到的变量、函数、类
#=====================================================================================================================
print("‘#’"*40)
#4、string模块(字符串模块)
# string模块是关于字符串的模块
import string
# 1.获取所有的十进制字符 (★★★★★)
print(string.digits) #0123456789
# 2.获取所有的大写字母
print(string.ascii_uppercase) #ABCDEFGHIJKLMNOPQRSTUVWXYZ
# 3.获取所有的小写字母
print(string.ascii_lowercase) #abcdefghijklmnopqrstuvwxyz
# 4.获取所有的字母 (★★★★★)
print(string.ascii_letters) #abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
# 5.获取所有的八进制或十六进制
print(string.octdigits) #01234567 (oct代表八进制)
print(string.hexdigits) #0123456789abcdefABCDEF (hex代表十六进制)
# 6.获取所有的标点符号
print(string.punctuation) #!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ (punctuation /ˌpʌŋktʃuˈeɪʃn/ n. 标点符号)
# 7.获取所有的空白符:空格,tab,回车,换行等
print(string.whitespace)
# 8.获取所有可打印的字符
print(string.printable)
print("‘#’"*40)
#=====================================================================================================================
#5、os模块(系统模块 OS——Operating System)
import os
# 一、os模块下的函数
# 1.listdir(path):列出指定路径下所有的内容,包含文件和文件夹, (★★★★★)
# 返回一个列表,其中的元素是文件或文件夹的名称
pa = r"D:\code\python" # 绝对路径
r1 = os.listdir(pa)
print(r1) #['day1', 'day10', 'day11', 'day12', 'day13', 'day14', 'day16', 'day17.1', 'day2', 'day3', 'day4', 'day5', 'day6', 'day7', 'day8', 'day9']
# 2.mkdir(path):创建一个目录 (★★★★★)
# os.mkdir(r"test") # 相对路径下创建一个名为“test”的文件夹(就是在当前代码文件同级创建)
# open():创建一个文件
# f1 = open(r"a1.txt","w",encoding="utf-8") #会在当前代码文件同级创建一个文件
# 3.rmdir(path):删除一个目录
# os.rmdir(r"aaa")
# 4.remove(path):删除一个文件
# os.remove(r"a1.txt")
# 5.rename(old,new):给指定的文件或文件夹重命名
# os.rename(r"test","rename")
# os.rename(r"a1.txt",'file.txt')
# 二、os.path模块下的函数 (★★★★★)
# 1.join(父路径,子路径):拼接路径
p1 = r"/Users/zhangzong/Desktop/python"
subpath = r"Day2Code"
# a.+,不推荐使用,原因:python是跨平台的,但是,如果采用+的方式拼接路径,不同操作系统中拼接的方式不同
# new_path1 = path + "/" + subpath # 在windows中,new_path1 = path + "\\" + subpath
# print(new_path1)
# b.join()
new_path2 = os.path.join(p1,subpath)
print(new_path2) #/Users/zhangzong/Desktop/python\Day2Code
# 2.split(path):对路径进行分割,结果为一个元组,格式:(父路径,子路径)
p_2 = r"/Users/zhangzong/Desktop/python\Day2Code\print.py"
r1 = os.path.split(p_2)
print(r1) #('/Users/zhangzong/Desktop/python\\Day2Code', 'print.py')
# 3.splitext(path):对路径进行分割,结果为一个元组,格式:(父路径,扩展名)
# 如果path是一个文件夹,则结果为(父路径,""),如果path是一个文件,则结果为(父路径,".扩展名")
print(os.path.splitext(p1)) #('/Users/zhangzong/Desktop/python', '')
print(os.path.splitext(p_2)) #('/Users/zhangzong/Desktop/python\\Day2Code\\print', '.py')
# 4.isfile(path):判断指定路径是否是文件(所有路径不是文件就是文件夹)
print(os.path.isfile(r"D:\code\python\day1")) #False
print(os.path.isfile(r"D:\code\python\day1\text01.py")) #True
# 5.isdir(path):判断指定路径是否是文件夹(文件file,文件夹dir)
print(os.path.isdir(r"D:\code\python\day1")) #True
print(os.path.isdir(r"D:\code\python\day1\text01.py")) #False
# 6.exists(path):判断path是否存在(exists /ɪɡˈzɪsts/ v. 存在;出现)
print(os.path.exists(r"/Users/zhangzong/Desktop/python\Day2Code\print.py")) #False
# 7.getsize(path):获取一个文件的字节大小,常用于文件读写中
print(os.path.getsize(r"D:\code\python\day1\text01.py")) #255
四、第三方模块
安装第三方模块的方式:
- 方式一:在pycharm:file—>settings---->Project—>Project Interpreter ---->+
- 方式二:在cmd中,执行pip install xxxx -i 镜像源
- 方式三:安装Anaconda,相当于Python,只不过其中已经安装了180+以上的第三方模块
五、练习递归遍历目录
import os
# 需求:封装一个函数,获取指定路径下所有的md文件
def get_md_file(path):
# 判断指定路径是否存在,如果不存在,则没有必要执行后面的代码
if not os.path.exists(path):
print("路径不存在,无法操作")
return
# 判断指定路径是否是文件。如果是文件,则没有必要执行后面的代码
if os.path.isfile(path):
print("路径是一个文件")
if path.endswith(".md"):
print(f"{path}是一个md文件")
return
# 如果代码可以执行到此处,则表示path是一个文件夹
# 获取path下所有的内容
filelist = os.listdir(path) #此时返回的是path文件夹的目录列表
# print(filelist)
# 遍历fileList,拼接路径
for filename in filelist:
subpath = os.path.join(path,filename)
# print(subpath)
# 判断子路径是否是文件
# 如果是文件,则继续判断是否是md文件
if os.path.isfile(subpath):
if os.path.splitext(subpath)[1] == ".md":
print(f"{subpath}是一个md文件")
else:
# 如果是文件夹,则继续向里遍历
# 会重复前面的的代码,则可以采用递归的方式执行
get_md_file(subpath)
if __name__ == '__main__':
path = r"/Users/yangyang/Desktop/coding14"
get_md_file(path)