循序渐进Python程序设计 课件 第6、7章 模块应用、文件处理_第1页
循序渐进Python程序设计 课件 第6、7章 模块应用、文件处理_第2页
循序渐进Python程序设计 课件 第6、7章 模块应用、文件处理_第3页
循序渐进Python程序设计 课件 第6、7章 模块应用、文件处理_第4页
循序渐进Python程序设计 课件 第6、7章 模块应用、文件处理_第5页
已阅读5页,还剩91页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

01020304第6章模块应用6.1模块基本概念6.2常用内置模块的使用6.3创建自定义模块6.4综合应用案例第6章模块应用6.1.1模块的定义与作用6.1模块基本概念在Python中,模块(Module)是一个包含了Python定义和语句的文件,其文件名就是模块名加上

.py

扩展名(编译后的扩展名为.pyc)。模块用于实现特定的功能或一组相关功能,可以包含函数、类、变量等,是代码复用和组织的基本单元。1.模块的定义2.模块的作用在Python程序设计中,模块扮演着至关重要的角色,它为程序开发带来了诸多便利和优势,其主要作用有:(1)代码复用(2)代码组织与管理(3)提高代码可维护性(4)促进团队协作(5)封装与隐藏实现细节(6)扩展功能第6章模块应用6.1.1模块的定义与作用6.1模块基本概念3.模块的分类【练一练6.1】安装农历处理模块:lunardate。(1)标准库模块。是Python自带的模块,也称为内置模块,无需安装即可使用。例如,

用于数学计算,提供了许多数学函数和常量的math模块;用于生成随机数的random模块;提供了与操作系统交互功能的os模块,等等。(2)第三方模块。由其他开发者或组织开发的模块,需要使用包管理工具(如

pip)进行安装,如

numpy、pandas、Django

等。(3)自定义模块:开发者根据自己的需求创建的模块,能将相关功能封装起来,提高代码的复用性和可维护性。第6章模块应用6.1.1模块的定义与作用6.1模块基本概念4.模块的结构模块通常由以下部分组成:(1)模块文档字符串(可选)模块文档字符串是模块开头的一个由三引号界定的字符串,用于描述模块的功能、用途和使用方法等信息。可以通过模块的

__doc__

属性访问。(2)__all__

变量(可选)在Python模块里,__all__

是一个特殊的变量,它是一个由字符串组成的列表,主要用于控制使用“from模块名import*

”语句导入模块时可以使用的成员。如果模块中未定义__all__

变量,当使用

“from模块名import*

”语句导入模块时,Python解释器默认会导入模块中所有不以单下划线

_

开头的成员(包括函数、类、变量等)。但通过定义

__all__

变量,可以改变这种默认行为。【练一练6.2】在Python的交互式解释器中,先使用语句“importmath”导入math模块,再输入“math.__doc__”后回车,查看math模块文档字符串。deffunc1():print("这是函数func1")deffunc2():print("这是函数func2")__all__=['func1']【例6.1】假定模块mymodule.py的内容为:z6j1s1.py文件(与mymodule.py位于同一文件夹)的内容为:frommymoduleimport*func1()func2()在

mymodule.py

文件中,__all__

变量被定义为

['func1'],这意味着当使用方式“

frommymoduleimport*

”导入模块时,只有

func1

会被导入,func2

不会被导入,调用

func2()

会引发

NameError异常。第6章模块应用6.1.1模块的定义与作用6.1模块基本概念4.模块的结构(3)导入语句(可选)导入语句用于引入其他模块的功能,使当前模块可以使用这些模块中定义的函数、类和变量等。导入语句通常位于模块文档字符串之后。(4)全局变量定义全局变量是在模块级别定义的变量,它们在整个模块中都可以访问。全局变量通常用于存储模块需要共享的数据。(5)函数定义函数是模块中封装特定功能的代码块。可以定义多个函数,每个函数实现不同的功能。(6)类定义类是面向对象编程的重要概念,用于封装数据和行为。在模块中可以定义一个或多个类。(7)主程序代码有些模块除了提供功能供其他模块使用外,还可以直接作为脚本运行。语法格式:

if__name__=="__main__":

#主程序代码作用:仅在模块直接运行时执行主程序代码。作为模块被导入到其他程序或模块时不会被执行。也可编写调试模块功能的相关代码。第6章模块应用6.1.1模块的定义与作用6.1模块基本概念5.模块的编辑在Python中,模块的编译是一个重要的过程,它有助于提高程序的执行效率和保护源代码。(1)Python代码的编译机制Python是一种解释型语言,但在运行代码之前,它会将

.py

文件编译成字节码(Bytecode),字节码文件的扩展名为

.pyc

。Python在首次运行脚本或导入模块时,会自动检查.py文件的修改时间。若.py文件有更新或缺少对应的.pyc文件,解释器会重新编译.py文件生成新的.pyc文件(存储在__pycache__目录中)。(2)使用py_compile编译模块py_compile

模块可以用于编译单个Python文件。【例6.2】(假定存在文件c:\mytools.py):importpy_compilepy_pile(r'c:\mytools.py')如果执行成功,会在C盘根目录生成一个对应的

.pyc

文件。【练一练6.3】创建c:\mytools.py文件,在其中定义一个全局变量和一个函数后将其编译。再在另一个py文件中导入该模块,输出模块中变量的值,调用模块中定义的函数并输出相应的函数值。第6章模块应用6.1.1模块的定义与作用6.1模块基本概念5.模块的编辑(3)使用

compileall

编译模块compileall

模块可以编译同一目录下的所有Python文件。【例6.3】(假定D盘根目录存在myModules文件夹,且该文件夹中存在多个py文件)。importcompileallpile_dir(r'D:\myModules')上述代码会递归地编译指定目录下的所有

.py

文件,并生成对应的

.pyc

文件。第6章模块应用6.1.2模块的导入与使用6.1模块基本概念1.使用import语句导入模块语法格式:import模块名[as别名]使用说明:(1)import支持一次导入多个模块,每个模块之间使用半角逗号分隔。(2)[as别名]部分为模块定义别名。可以缺省。【例6.4】importtime #导入1个模块importrandom,pygameaspm#导入2个模块,并为pygame模块取别名为pm(3)模块导入之后通过“.”操作符调用模块成员(变量、函数或类)。

调用模块变量的语法格式:模块名.变量名

调用模块类或函数的语法格式:模块名.类名或函数名(参数列表)【例6.5】importmathprint(math.cos(2)) #调用math模块的cos函数,输出cos(2)的函数值print(math.pi) #调用math模块的变量pi,输出该变量的值第6章模块应用6.1.2模块的导入与使用6.1模块基本概念2.使用from...import语句导入模块使用“from...import...”方式导入模块之后,无须添加前缀,可以像使用当前程序中的内容一样使用模块中的内容。此种方式的语法格式:【例6.6】frommathimportpi,sin,cos #从math模块导入3个成员print(sin(1)+cos(2)) #直接调用math模块的sin和cos函数print(pi) #直接调用math模块的变量pi使用说明:(1)可以同时导入模块的多个成员。成员名之间使用半角逗号分隔。(2)可以通过“[as别名]”方式为成员命名别名(可缺省)。(3)“成员名”也可以是通配符“*”,表示导入模块中所有不以单下划线

_

开头的成员。如果模块中定义了变量__all__,则导入该变量设置的成员。(4)以这种方式导入的模块成员可以直接调用,无需使用"."操作符。from模块名import成员名[as别名]第6章模块应用6.1.2模块的导入与使用6.1模块基本概念3.模块的动态导入动态导入模块指的是在程序运行时根据具体条件来决定导入哪个模块,而非在代码编写阶段就固定导入某些模块。下面为你详细介绍几种实现动态导入模块的方法:(1)使用__import__函数__import__是Python的内置函数,能够实现动态导入模块。基本语法:【例6.7】假定某程序的功能有二个:第一个功能的相关函数保存在fun1.py,第二个功能的相关函数保存在fun2.py。程序运行时根据用户的选择动态导入相应的模块。fun1和fun2模块中均定义了run函数(用于实现相应的功能)s=input("请选择操作(1-功能12-功能2其他-结束):")matchs:case'1'|'2':md=__import__(f"fun{s}")#根据s的值动态导入模块md.run()参数说明:name是要导入的模块名(字符串)。fromlist指定导入的成员(成员名均为字符串),为空则返回顶层模块。__import__(name,fromlist=())第6章模块应用6.1.2模块的导入与使用6.1模块基本概念3.模块的动态导入(2)使用importlib.import_module函数importlib是Python标准库中的一个模块,importlib.import_module函数提供了更便捷、更推荐的动态导入方式。基本语法:参数说明:name是要导入的模块名(字符串)importimportlibmd=importlib.import_module(name)【练一练6.4】修改上例代码,使用import_module函数动态导入模块。第6章模块应用6.1.2模块的导入与使用6.1模块基本概念4.导入机制与搜索路径Python模块导入机制和搜索路径相互配合,确保了模块能够被正确地查找、加载和使用。理解这些机制对于编写复杂的Python程序和管理模块至关重要。(1)模块导入的基本流程当Python执行import语句时,会按照以下步骤进行操作:①检查sys.modules。Python解释器首先检查sys.modules字典。sys.modules存储了所有已经导入的模块。如果要导入的模块已经存在于sys.modules中,Python会直接使用该模块对象,而不会再次加载和执行模块代码。②查找模块。如果模块不在sys.modules中,Python会在指定的搜索路径中查找模块。③加载和执行模块。找到模块文件后,Python会将模块的代码加载到内存中,并执行模块中的顶级代码(如全局变量的定义、函数和类的定义等)。同时,会为该模块创建一个命名空间,模块中的所有对象都存储在这个命名空间中。④添加到sys.modules。将加载的模块对象添加到sys.modules字典中,以方便后续导入操作的检查。第6章模块应用6.1.2模块的导入与使用6.1模块基本概念4.导入机制与搜索路径(2)模块搜索路径。Python查找模块时,会按照sys.path列表中指定的路径依次进行搜索。sys.path是一个包含多个字符串的列表,每个字符串代表一个搜索路径。【练一练6.5】编写代码查看sys.path的内容。sys.path通常包含以下几类路径:①当前脚本所在的目录:即执行Python脚本的当前工作目录。②Python的标准库目录:包含Python自带的标准库模块。③PYTHONPATH环境变量指定的路径。PYTHONPATH是一个环境变量,用户可以将自定义的模块路径添加到该环境变量中,Python会将这些路径添加到sys.path中。④第三方库安装目录。使用pip安装的第三方库通常会安装在Python的site-packages目录下,该目录也会包含在sys.path中。第6章模块应用6.1.3模块的组织与管理6.1模块基本概念1.使用包组织模块包(Package)是一种组织Python模块的方式,本质上是一个包含多个模块的文件夹。也可以包含其他包(称为子包)。通过将相关的模块或包组织在一起,实现代码的结构化和模块化。包通常包含一个特殊的

__init__.py

文件(可选),其主要作用是:(1)完成初始化。在包被导入时自动执行

__init__.py

文件中的代码,一般用于全局设置、初始化变量或加载必要资源。(2)控制包的导入行为。可以在

__init__.py

文件中使用

__all__

变量来控制使用

“from包名import*

”语句时导入的模块或成员。__all__

是一个列表,包含了需要导入的模块名。(3)简化包的导入。__init__.py

文件中可以将包内的模块或子包中的对象导入到包的命名空间中。其他模块导入包时,不再需要导入其模块或子包中的对象,从而简化导入语句。(4)包级别的命名空间管理。__init__.py

文件中可以用来定义包级别的函数、类和变量,这些对象可以在整个包内被访问。【练一练6.6】在Python的安装目录中找到Lib\ctypes文件夹,查看该包的文件组成,及__init__.py

文件中的内容。第6章模块应用6.1.3模块的组织与管理6.1模块基本概念2.使用库组织包或模块库(Library)是具有相关功能模块的集合,是为了实现某一类特定功能而编写的代码组合。库可以由单个包组成,也可以由多个包和模块组合而成。也可以包含一些非Python文件,如配置文件、数据文件、C扩展模块(.pyd

.so

文件)等。库和包的主要区别:(1)库包含一个或多个包和模块,包是一种组织Python模块的方式,本质上是一个包含多个模块的文件夹。(2)库可以包含非Python文件,包只能包含模块和子包。(3)库侧重于提供完整的、面向特定领域的功能解决方案。开发者使用库可以快速实现复杂的功能,而无需从头编写大量代码。包主要用于组织和管理代码,使代码结构更加清晰、易于维护。通过将相关的模块组织在一个包中,可以避免命名冲突,提高代码的可读性和可维护性。第6章模块应用6.1.3模块的组织与管理6.1模块基本概念3.包或库的导入(1)使用import

语句导入整个包或库语法格式:import包或库名使用说明:这种方式会将整个包或库导入到当前命名空间,使用其中的对象(模块、函数、类、变量)时,需要使用"."操作符访问。可以使用as关键字为包或库指定别名。【例6.8】播放MP3音频(适用于windows平台,需有音频文件E:\girl.mp3)importctypes #导入Python自带的ctypes包winmm=ctypes.windll.winmm #加载Windows动态库winmm.dllcmd=b"openE:\\girl.mp3typempegvideoaliasmusic"result=winmm.mciSendStringA(cmd,None,0,None)#打开音频文件ifresult!=0:print("打开音频文件失败")else:result=winmm.mciSendStringA(b"playmusic",None,0,None)#播放音频文件ifresult!=0:print("播放音频文件失败")else:print("音频播放中...")input("按回车键停止播放...")#等待用户按回车键winmm.mciSendStringA(b"closemusic",None,0,None)#关闭音频文件第6章模块应用6.1.3模块的组织与管理6.1模块基本概念3.包或库的导入(2)使用from...import...

语句导入包或库的特定对象语法格式:from包

或库名import对象名使用说明:可以同时导入多个对象(模块、类、函数或变量)。对象之间使用半角逗号分隔。也可以使用as关键字为对象指定别名。导入的对象可以直接使用。【例6.9】假设包

my_package

有子包

sub_package(有funs.py

模块)【练一练6.7】修改上例代码,只从ctypes包中导入windll对象。或者,使用

from...import*

语句导入所有对象。有二种方式可以导入子包或包中的模块:语法格式1:语法格式2:import包名.子包名.模块名from包名.子包名import模块名importmy_package.sub_package.funs或frommy_package.sub_packageimportfuns【练一练6.8】修改上例代码,动态导入ctypes包中的windll对象。第6章模块应用6.1.3模块的组织与管理6.1模块基本概念3.包或库的导入(3)绝对导入与相对导入绝对导入基于sys.path列表进行模块查找,该列表包含标准库路径、第三方库路径及当前工作目录等。在复杂项目中,绝对导入能明确模块来源,避免路径歧义,确保跨模块调用的准确性。相对导入是相对于当前模块的位置来查找要导入的模块。它使用点号(.)来表示相对路径:点(.)表示当前包,两个点(..)表示当前包的父包,以此类推。相对导入只能在包内部使用。【例6.10】假设包

my_package包的结构如右图所示,含二个模块funs1.py

和funs2.py在funs1.py中使用相对导入方式导入funs2.py中的成员:from.funs2import*在test.py中使用相对导入方式导入funs2.py中的成员:from..funs.funs2import*第6章模块应用6.2.1sys模块6.2常用内置模块的使用sys模块中提供了一系列与Python解释器交互的函数和变量,用于设置或读取Python运行时环境信息。sys模块中常用的变量与函数下表所示。【例6.11】importsysprint(sys.argv) #输出命令行参数列表print(sys.version) #输出Python解释器的版本信息print(sys.path) #输出模块搜索路径exit() #退出脚本【练一练6.9】定义a=b=[1,2,3],输出数据对象[1,2,3]的引用计数。第6章模块应用6.2.2os模块6.2常用内置模块的使用os模块提供了访问操作系统服务的功能,该模块中常用的变量与函数下表所示。第6章模块应用6.2.2os模块6.2常用内置模块的使用【例6.12】fromosimportsystem,startfilefromos.pathimportisfile,isdirifisfile("D:\\a.docx"): #当文件存在时startfile("D:\\a.docx") #使用Windows的默认程序打开文件ifisdir("d:\\myd"):#当文件夹存在时system("rd/s/qd:\\myd") #删除文件夹(可以非空)【练一练6.10】(1)输出计算机名称。(2)如果D盘根目录不存在mydatas文件夹,则创建该文件夹。(3)利用startfile函数播放视频。(4)调试以下程序,分析执行效果。fromosimportsystemsystem("copy/yc:\\x*.txtd:\\mydatas")system("explorer")第6章模块应用6.2.3random模块6.2常用内置模块的使用random为随机处理模块,在该模块中定义了多个可产生各种随机数的函数,该模块中常用的变量与函数下表所示。第6章模块应用6.2.3random模块6.2常用内置模块的使用【例6.13】随机产生6个[1,36]上的整数,并按递增排序输出。fromrandomimportsamplea=sample(range(1,37),6) #随机产生6个[1,36]上的整数。a为列表a.sort() #调用列表的内置函数完成递增排序print(a)【练一练6.11】下面哪些表达式一定能随机产生一个[0,100]上的整数。(1)a=sample(range(101),1)[0](2)a=randint(0,100)(3)a=getrandbits(8)(4)a=choice(range(101))(5)a=uniform(9,100)第6章模块应用6.2.4time模块6.2常用内置模块的使用time模块主要用于日期和时间的处理。1.时间格式time模块有3种方式来表示时间:(1)时间戳。是从1970年1月1日00:00:00开始到现在的秒数。(2)时间元组struct_time。共有9个元素:tm_year(年),tm_mon(月),tm_mday(日),tm_hour(小时,0~23),tm_min(分,0~59),tm_sec(秒,0~59),tm_wday(星期,0~6,0表示周一),tm_yday(一年中的第几天),tm_isdst(是否为夏令时)。(3)时间字符串。时间字符串约定了下表所示的格式字符。第6章模块应用6.2.4time模块6.2常用内置模块的使用time模块主要用于日期和时间的处理。2.常用函数time

模块是Python标准库中用于处理时间相关操作的模块,它提供了多种函数和方法,可用于获取当前时间、进行时间格式转换、实现时间延迟等操作。该模块中常用的变量与函数下表所示。第6章模块应用6.2.4time模块6.2常用内置模块的使用【例6.14】输出当前日期的星期。fromtimeimportlocaltimetm=localtime() #得到当前日期对应的时间元组weeks=["一","二","三","四","五","六","日"]print(f"{tm[0]}年{tm[1]}月{tm[2]}日是星期{weeks[tm[6]]}")#输出日期及星期【练一练6.12】(1)输入日期,输出该日期的星期。提示:strptime("2020-3-18","%Y-%m-%d")可以得到2020年3月18日对应的时间元组。(2)如何测试某段代码需运行的时间?第6章模块应用6.2.5datetime模块6.2常用内置模块的使用与time模块相比,datetime模块专注于日期和时间的高级处理,提供多种类表示日期、时间及其差值,简化了计算、格式化和单位转换,适用于时间运算、比较等业务场景。下面重点介绍datetime模块的2个类:date和timedelta。

1.date类在datetime模块中,date

类处理日期信息。构造函数语法:date(year,month,day)参数说明:根据year(年份)、month(月份)、day(日)创建date对象。各参数均为整数。创建date对象时,会自动检查日期数据的有效性,如果日期数据无法转换为date对象,会触发ValueError异常。【练一练6.13】尝试使用date(2025,2,29)创建date对象。第6章模块应用6.2.5datetime模块6.2常用内置模块的使用date类的主要成员见下表。第6章模块应用6.2.5datetime模块6.2常用内置模块的使用【例6.15】输出当前日期的相关信息。fromdatetimeimportdate #从datetime模块导入date类td=date.today() #得到表示当前日期的date对象print(f"今天是{td.year}年{td.month}月{td.day}日")#输出当前日期a=td.timetuple() #得到日期对应的时间元组n=a.tm_yday #确定日期是一年的第几天print(f"今天是一年中的第{n}天")【练一练6.14】(1)输入日期,利用date对象输出该日期的星期。(2)确定当前日期当月的第一天是星期几。第6章模块应用6.2.5datetime模块6.2常用内置模块的使用2.timedelta类在

datetime

模块中,timedelta

类用于表示两个日期或时间之间的差值,它支持日期和时间的算术运算。构造函数语法:timedelta(days,seconds,microseconds,milliseconds,minutes,hours,weeks)参数说明:(1)days:表示天数,为整数或浮点数,默认值是0。(2)seconds:表示秒数,为整数或浮点数,默认值是0。(3)microseconds:表示微秒数,为整数或浮点数,默认值是0。(4)milliseconds:表示毫秒数,为整数或浮点数,默认值是0。(5)minutes:表示分钟数,为整数或浮点数,默认值是0。(6)hours:表示小时数,为整数或浮点数,默认值是0。(7)weeks:表示周数,为整数或浮点数,默认值是0。第6章模块应用6.2.5datetime模块6.2常用内置模块的使用【例6.16】确定当前日期100天后的日期。fromdatetimeimportdate,timedeltatd=date.today() #得到当前日期days=timedelta(days=100) #将100天转换为timedelta对象new=td+days #得到100天的day对象print(f"100天后的日期是:{new.year}年{new.month}月{new.day}日")【练一练6.15】确定当前日期100天前的日期。第6章模块应用6.2.6math模块6.2常用内置模块的使用math模块提供了许多数学运算函数,主要成员见右表所示。【例6.17】importmathmath.pow(5,3) #结果125.0math.sqrt(9) #结果3.0math.ceil(5.2) #结果6math.floor(5.2) #结果5math.fmod(5,2) #结果1.0【练一练6.16】比较int(3.56)、ceil(3.56)和floor(3.56)的值,并分析原因。第6章模块应用6.2.7re模块6.2常用内置模块的使用Python中的re模块用于处理正则表达式,提供了文本匹配查找、文本替换、文本分隔等功能。1.正则表达式正则表达式是由普通字符(如字母、数字)和特殊字符(元字符、预定义字符)组成的字符串模式,用于描述字符串的特征或规则,高效地进行字符串的匹配和处理。(1)元字符元字符指在正则表达式中具有特殊含义的字符,用来规定其前导字符在目标对象中出现的模式。常用元字符见右表。第6章模块应用6.2.7re模块6.2常用内置模块的使用(2)预定义字符预定义字符以简洁的方式表示特定的匹配模式。常用预定义字符见下表。第6章模块应用6.2.7re模块6.2常用内置模块的使用2.常用函数re模块中常用的函数见下表。第6章模块应用6.2.7re模块6.2常用内置模块的使用【特别提示】(1)函数参数flag指定匹配标识。可设置为:re.I(忽略大小写)、re.A(根据ASCII字符集解析字符)、re.U(根据Unicode字符集解析字符)、re.X(允许使用多行、忽略空白字符、添加注释)、re.S("."可匹配换行符)、re.M(多行匹配)、re.L(本地化识别匹配)。【例6.18】importrepat=pile("[a-z]+",re.I) #编译正则表达式,忽略大小写s="Ilovemymotherland"a=re.findall(pat,s) #在字符串s中搜索所有匹配print(a) #输出:['I','love','my','motherland'](2)Pattern对象是通过编译正则表达式模式而得到的对象。使用Pattern对象可以更高效地多次执行相同模式的匹配操作,避免了每次匹配都重新编译正则表达式的开销。Pattern对象也有match、search、split、findall、finditer、suB.subn等内置方法。【练一练6.17】将上例改为调用pat.findall实现。第6章模块应用6.2.7re模块6.2常用内置模块的使用【特别提示】(3)sub函数的rep参数可以是字符串或者函数,用于指定替换匹配项的内容。如果是字符串,其中可以使用

\n(n

是1到99的数字)来引用匹配模式中的捕获组;如果是函数,该函数会接收一个

Match

对象作为参数,并返回一个用于替换的字符串。【例6.19】使用字符串替换importrepattern=r'\d+' #定义正则表达式,匹配所有数字s='Thecodeis188-2580-1033.'new=re.sub(pattern,'X',s,2) #将s中的数值替换为X。仅替换2次print(new) #输出:ThecodeisX-X-1033.第6章模块应用6.2.7re模块6.2常用内置模块的使用【例6.20】使用捕获组进行替换importrepat=r'(\w+)(\w+)' #定义正则表达式,模式包括二组s='WuJian'new=re.sub(pat,r'\2\1',s) #将匹配到的2组数据互换print(new) #输出:JianWu【例6.21】使用函数进行替换importrepat=r'\d+' #定义正则表达式,匹配所有数字s='Thecodeis188-2580-1033.'deftrans(match): #定义替换函数,将匹配到的数字+1num=int(match.group())returnstr(num+1)new=re.sub(pat,trans,s,1) #替换一次print(new) #输出:Thecodeis189-2580-1033.【练一练6.18】将上例改为每个连续的数字都乘以3。第6章模块应用6.2.7re模块6.2常用内置模块的使用Match

对象是当正则表达式模式在字符串中匹配成功时所返回的对象。它包含了关于匹配结果的详细信息,常用属性和方法见下表。第6章模块应用6.2.7re模块6.2常用内置模块的使用【例6.22】使用捕获组进行替换fromreimportmatchdate="2024-5-16isadate."pat=r'(\d{4})-(\d{2})-(\d{2})' #模式有3个分组mat=match(pat,date) #从首字符开始匹配ifmat: #如果匹配成功print("整个匹配结果:",mat.group(0))print("年:",mat.group(1))print("月:",mat.group(2))print("日:",mat.group(3))else:print("未匹配到内容。")程序的输出结果为:整个匹配结果:2024-5-16年:2024月:5日:16第6章模块应用6.2.7re模块6.2常用内置模块的使用match函数是从字符串的首字符开始匹配,如果首字符匹配成功则返回匹配对象,否则返回None。而search函数会在整个字符串中搜索,可以在任意位置进行匹配。【例6.23】使用捕获组进行替换fromreimportmatch,searchpat=r'\d+'s='Thecodeis188-2580-1033.'mt=match(pat,s)ifmt:print("match:",mt.group())else:print("match:None")mt=search(pat,s)ifmt:print("search:",mt.group())else:print("search:None")第6章模块应用6.3.1创建自定义模块的主要步骤6.3创建自定义模块创建自定义模块的步骤和项目规模密切相关。项目规模不同,创建模块的过程也会有所差别。本节仅从简单项目的角度,概述创建自定义模块的主要步骤。(1)需求分析。分析模块的功能需求,确定需要定义的全局变量、函数或类。如果功能相对复杂,还需考虑将各功能细分为多个模块或包,以方便各功能的调试与团队分工协作。(2)编写模块代码。在创建的Python文件中编写实现模块功能的实现代码。Python模块是以.py为后缀的代码文件,用于组织可复用的代码单元。在模块中可以定义函数实现特定功能,使用类封装数据和行为模型,并通过变量存储共享配置或常量。例如数据分析模块可能包含数据清洗函数,而图形模块则可定义图形类来管理属性和绘制方法。(3)添加文档字符串。在模块、函数和类的开头添加文档字符串,用于描述其功能、参数和返回值等信息。(4)必要时,可以定义__all__变量,明确以“from模块名import*”方式导入模块时允许导入的模块成员。(5)如果需要创建包,可以将各功能模块保存到同一个文件夹中。也可创建__init__.py文件,在该文件中定义包级别的函数、类和变量,或将包内的模块或子包中的对象导入到包的命名空间中。(6)测试与优化。在模块文件中可以添加测试代码,用于验证模块的功能是否正常。通常在“if__name__=='__main__'”语句中添加测试代码。第6章模块应用6.3.2创建自定义模块需要遵守的规范6.3创建自定义模块1.命名规范在Python中,模块命名应遵循小写字母加下划线风格(如data_processing),并确保名称具有描述性且符合标识符规则(字母、数字和下划线组成,不以数字开头)。虽然常见缩写(如http)可以接收,但应避免随意创造不常见的缩写(如proc代替processing)。良好的模块名应准确反映功能(如文件处理模块名file_operations),避免使用模糊名称(如temp),除非在特定上下文中含义明确。这种命名方式既提升可读性,也符合Python社区惯例。2.代码结构规范Python通过缩进来定义代码块,建议统一使用4个空格(而非Tab)以确保跨编辑器一致性。正确的缩进能清晰体现代码层次结构(如函数体、循环等),错误的缩进会导致语法或逻辑错误。此外,应遵循模块化原则,将不同功能封装为独立函数或类,提升代码可维护性和复用性。第6章模块应用6.3.2创建自定义模块需要遵守的规范6.3创建自定义模块3.文档字符串规范自定义模块应添加文档字符串("""包裹),模块级文档字符串置于文件开头说明功能用途,函数/类文档字符串需描述参数、返回值及异常。关键代码处补充注释解释实现逻辑。4.全局变量使用规范应避免使用全局变量,因其作用域覆盖整个模块,会增加代码复杂性和调试难度。若必须使用,需以全大写命名(如MAX_VALUE),并在模块开头集中初始化,后续也应尽量避免修改全局变量的值。第6章模块应用6.3.3自定义模块的保存位置6.3创建自定义模块1.同目录保存将自定义模块与主程序放在同一目录是最简单的方式,直接使用import即可调用,无需额外的路径配置。但随着项目规模扩大,建议将模块按功能划分到不同子目录,以保持代码结构清晰。2.标准库路径保存虽然技术上可将自定义模块放入Python标准库路径(如Lib目录),但强烈不建议这样做。标准库是Python的核心组件,修改可能导致系统不稳定、影响其他项目,且在Python更新时,这些修改会丢失。3.第三方库路径保存通常为Python安装目录的Lib/site-packages目录。所有脚本均可导入该路径中的模块(包或库)。第6章模块应用6.3.3自定义模块的保存位置6.3创建自定义模块4.设置PYTHONPATH在Python里,自定义模块的保存位置和PYTHONPATH紧密相关,PYTHONPATH是Python解释器找模块时会搜索的路径。设置PYTHONPATH,能让解释器找到自定义模块。(1)临时设置。Windows:在命令提示符输入setPYTHONPATH=C:\模块存放路径;%PYTHONPATH%,多个路径用分号隔开,只在当前命令行会话期间有效。(2)永久设置。Windows:右键“此电脑”选“属性”,点“高级系统设置”,进“环境变量”,在“系统变量”里找到“Path”变量(没有“PYTHONPATH”就新建),编辑它,把模块路径添加进去后保存。(3)验证。设置好后,运行Python代码importsys;print(sys.path)

,如果输出里有你添加的模块路径,就说明设置成功。这样,只要设好PYTHONPATH,就能顺利导入模块使用。第6章模块应用6.3.4发布与分享6.3创建自定义模块1.打包成pip包将自定义模块打包成pip包是一种常见的发布方式,方便他人安装和使用。打包过程首先需要创建一个setup.py文件,这个文件是打包和分发的核心配置文件。在setup.py中,需要配置模块的元数据,包括模块名称、版本号、作者、描述、依赖项等信息。版本号的管理遵循语义化版本规范,即MAJOR.MINOR.PATCH格式。MAJOR版本号在有不兼容的API变更时递增,例如修改了函数的参数列表或返回值类型;MINOR版本号在有向下兼容的新功能添加时递增,如在模块中新增了一个函数,但不影响原有函数的使用;PATCH版本号在有向下兼容的错误修复时递增,例如修复了一个函数中的小漏洞。可以通过install_requires参数指定模块的依赖项。例如,如果模块依赖于numpy库,可以在setup.py中添加install_requires=['numpy']。这样,当其他人使用pipinstall安装你的模块时,pip会自动安装numpy库及其依赖。setup.py是用于打包和分发Python模块的脚本文件。将模块发布到PyPI或其他包管理系统时,setup.py

起着关键作用。setup.py文件中,主要使用setuptools

库的setup

函数设置项目配置信息。第6章模块应用6.3.4发布与分享6.2常用内置模块的使用【例6.24】setup.py配置参考模板fromsetuptoolsimportsetup,find_packagessetup( name='name' #项目名称 version='1.0.0', #项目版本号 description='...', #项目简短描述 long_description=open('README.md').read(), #项目说明文档 long_description_content_type='text/markdown', #详细描述的内容类型 author='YourName', #项目作者 author_email='your_email', #作者邮箱 url='...', #项目主页URL packages=find_packages(), #自动发现项目中的所有包 py_modules=[...], #项目包含模块 include_package_data=True, #是否包含非Python文件 package_data={'module':['data/*.txt']}, #字典,指定非Python文件 install_requires=[...], #项目运行时依赖的其他包 extras_require={...}, #字典,开发环境额外需要的包 classifiers=[...], #分类信息 entry_points={...}, #字典,命令行脚本入口 keywords='keyword1keyword2', #项目关键词 license='MIT' #开源许可证名称)第6章模块应用6.3.4发布与分享6.3创建自定义模块2.使用setuptools构建和发布setuptools是Python中用于构建和分发软件包的标准库。使用setuptools库来构建和发布包非常方便。通过在命令行中执行pythonsetup.pysdist命令,可以生成源代码发布包,生成的包文件通常位于dist目录下。然后,可以使用twine工具将生成的包上传到PyPI(PythonPackageIndex)等包索引平台。twine是一个安全的上传工具,它可以验证包的完整性并加密传输。在上传之前,需要先注册PyPI账号,并确保twine工具已经安装。执行twineuploaddist/*命令,按照提示输入PyPI账号和密码,即可将包上传到PyPI。在上传过程中,可能会遇到各种问题,如版本冲突、依赖项问题等。如果遇到版本冲突,需要修改setup.py中的版本号,确保版本号的唯一性。如果依赖项问题导致上传失败,需要检查依赖项的名称和版本号是否正确,并确保依赖项已经在PyPI上发布。第6章模块应用6.3.4发布与分享6.3创建自定义模块3.版本控制系统托管使用版本控制系统(如Git)将模块代码托管在代码仓库(如GitHuB.GitLab等)上,是一种常见的分享和协作开发方式。通过版本控制系统,可以方便地管理代码的版本历史、追踪代码的修改记录、进行分支管理等。在托管代码时,需要合理设置仓库的权限。对于开源项目,可以将仓库设置为公开,让任何人都可以查看和贡献代码。对于私有项目,则需要将仓库设置为私有,并管理好协作人员的权限,确保只有授权人员可以访问和修改代码。在协作开发过程中,要注意使用分支管理策略。通常,master分支用于存储稳定的生产版本代码,develop分支用于开发新功能。开发人员在自己的分支上进行开发,完成功能开发后,通过合并请求(如GitHub的PullRequest)将代码合并到develop分支或master分支。这样可以避免代码冲突,提高开发效率。第6章模块应用6.3.4发布与分享6.3创建自定义模块假设我们有一个模块my_module,包含一个函数greet,创建setup.py文件并将其打包发布到本地测试仓库(假设使用twine和testpypi)。【例6.25】setup.py配置参考模板#my_module.pydefgreet(name):returnf"Hello,{name}!"#setup.pyfromsetuptoolsimportsetup,find_packagessetup(name='my_module',version='1.0.0',author='YourName',author_email='your_email@',packages=find_packages(),description='Asimplegreetingmodule')然后在命令行中执行以下命令进行打包和发布:pythonsetup.pysdistbdist_wheeltwineupload--repository-url/legacy/dist/*第6章模块应用案例1:随机号码生成器6.4综合应用案例【问题描述】自定义函数randNums(start=1,end=36,n=6),随机生成n个[start,end]上的整数。要求:(1)参数均为正整数,且0<start<end。(2)函数返回值为元组,包含的n个整数无重复且升序排序。(3)只能在星期二、星期五和星期日调用该函数。第6章模块应用案例1:随机号码生成器6.4综合应用案例【案例分析】1.参数的有效性检查函数的三个参数必须均为正整数,且满足0<start<=end-n+1才能确保产生n个正整数。2.日期控制利用datetime.date.today()函数得到当前日期(date对象),再由该对象的weekday()函数得到星期数([0,6]上的整数,0表示星期一)。利用该星期数即可实现日期控制。3.随机生成n个无重复的[start,end]上的整数可利用random模块的内置sample函数实现。4.数据排序sample函数的返回值为列表,利用列表的内置函数sort可完成对列表的递增排序。第6章模块应用案例1:随机号码生成器6.4综合应用案例【参考代码】fromrandomimportsamplefromdatetimeimportdatedefrandNums(start=1,end=36,n=6):try:assertisinstance(start+end+n,int) #三个参数必须都是整数assert0<start<=end-n+1 #必须确保能产生n个正整数except:returnNonetd=date.today() #得到当前日期对象w=td.weekday() #得到当前日期的星期数ifwnotin(1,4,6):returnNone #必须是星期二、五或日。w=sample(range(start,end+1),n) #随机产生n个整数w.sort() #升序排序returntuple(w) #转换为元组作为函数返回值if__name__=="__main__": #直接运行模块时(用于测试)print("DDD",randNums())print(randNums(10,100,8))【拓展训练】为函数randNums增加一个可选参数ctrl,默认值为True,表示只能在星期二、星期五或星期日调用该函数。如果设置为False,则不进行日期控制。第6章模块应用案例2:强密码检测6.4综合应用案例【问题描述】编写函数checkpwd(pwd),检测字符串pwd是否为强密码,即满足以下条件的密码:(1)至少包含12个字符。(2)只能由数字、大小写英文字母组成。且必须含有这三类字符。第6章模块应用案例1:随机号码生成器6.4综合应用案例【案例分析】1.字符长度的检测使用Python的内置函数len可得到字符串的长度(即包含的字符个数)。2.字符类型检测使用re模块进行字符类型检测。(1)检查字符串是否仅由数字、大小写英文字母组成利用re.search函数,检查字符串是否匹配模式'[^a-zA-Z0-9]+'。如果匹配,说明含有其他字符。否则,说明字符串仅由数字、大小写英文字母组成。(2)检查字符串是否包含数字利用re.search函数,检查字符串是否匹配模式'[0-9]'。如果匹配,说明包含数字。否则不包含数字。(3)检查字符串是否包含大写字母和小写字母利用re.search函数,检查字符串是否匹配模式'[A-Z]'。如果匹配,说明包含大写字母。否则不包含大写字母。检查字符串是否匹配模式'[a-z]'。如果匹配,说明包含小写字母。否则不包含小写字母。第6章模块应用案例1:随机号码生成器6.4综合应用案例【参考代码】importredefcheckpwd(pwd:str)->bool:#检查字符串是否仅由数字、大小写英文字母组成ifre.search('[^a-zA-Z0-9]+',pwd):returnFalse#检查字符串是否包含数字ifnotre.search('[0-9]',pwd):returnFalse#检查字符串是否包含大写字母ifnotre.search('[A-Z]',pwd):returnFalse#检查字符串是否包含小写字母ifnotre.search('[a-z]',pwd):returnFalsereturnTrueif__name__=="__main__": #测试示例tests=["abc123","abABCc123","9AB00C1","abcDEW","ab#c12=3AB"]forsintests:result=checkpwd(s)print(f"'{s}':{result}")【拓展训练】(1)不使用re模块,如何实现本案例的全部功能?(2)要求字符串中数字、大写字母和小写字母这三类字符中至少包含二类,如何实现?01020304第7章文件处理7.1文本文件的读写7.2二进制文件的读写7.3CSV文件的读写7.4使用Excel工作簿057.5综合应用案例第7章文件处理7.1.1什么是文本文件7.1文本文件的读写文本文件是以字符为基本单位组织数据的文件类型,通过编码(如UTF-8、GBK)将字符转换为二进制存储。2.特点​内容可读性:​​可直接阅读(字母、数字、标点)。​编码方式:​​常见编码包括ANSI、GBK、UTF-8、GB18030。​结构简单:​​由字符行组成,行间以换行符分隔。1.什么是文本文件3.应用场景存储文档资料(文章、报告)配置文件(软件参数)数据记录(日志文件、.csv文件)编程代码(.py文件默认UTF-8编码)7.1.2文本文件的读写Python文件读写基本步骤:​​“打开→操作→关闭”7.1.2文本文件的读写第7章文件处理7.1文本文件的读写7.1.2文本文件的读写7.1.2文本文件的读写第7章文件处理7.1文本文件的读写1.打开文本文件练一练:​​

在文件存在和不存在时,分别用'r+'、'w+'、'x+'、'a+'模式打开文件,观察是否触发异常并分析原因。语法:​​open(file,mode,buffering,encoding,errors)file:文件名(不指定路径则在当前目录打开)。mode:打开模式(见下表)。encoding:设置编码方式(如"UTF-8")。errors:错误处理方式('strict'、'ignore'、'replace')。7.1.2文本文件的读写第7章文件处理7.1文本文件的读写2.​操作文本文件(1)读取数据以'r'、'r+'、'w+'、'a+'或'x+'模式打开文件后,可以利用文件对象的内置方法(见下表)读取文件数据。f=open("c:/test.txt",encoding='utf-8')s=f.read(5);print(s)s=f.readline(6);print(s)s=f.readlines(30);print(s)s=f.readlines();print(s)f.close()【练一练7.2】三种读内置函数的使用示例7.1.2文本文件的读写7.1.2文本文件的读写第7章文件处理7.1文本文件的读写2.​操作文本文件(2)将数据写入文本文件

以'w'、'w+'、'r+'、'x'、'x+'、'a'或'a+'模式打开文件后,可以利用文件对象的内置方法(见下表)将数据与入文本文件。f=open('c:/test.txt','w',encoding='utf-8') #以'w'模式打开文本文件f.write("勤能补拙") #写入字符串(未使用换行符)f.write("学海无涯苦作舟/n") #写入字符串(使用换行符)a=["宝剑锋从磨砺出","梅花香自苦寒来"]f.writelines(a) #写入字符串列表(未使用换行符)a=["\n有志者事竞成\n","知识就是力量"]f.writelines(a) #写入字符串列表(使用换行符)f.close()【例7.3】两种写内置函数的使用示例7.1.2文本文件的读写7.1.2文本文件的读写第7章文件处理7.1文本文件的读写2.​操作文本文件(3)同时读写文本文件

以"r+"、"w+"、"a+"和"x+"模式打开文本文件后,既可以从文件中读取数据,也可以将数据写入文件。通常需要借助读写重定位完成相关操作。withopen("d:/zf.txt","r+",encoding="ANSI")asf:f.seek(4)#读写位置移到了文件第4个字节之后f.write("化为")#“就是”替换为“化为”f.seek(0)

#文件读写位置移到文件开头s=f.read()#读取文件中的全部数据print(s)#输出结果为:知识化为力量【例7.5】(假定文件d:/zf.txt采用ANSI编码,文件内容为:知识就是力量)(4)读写重定位

对文件进行读写操作时,读写的位置会自动后移。必要时,也可以通过文件对象的内置方法seek重新定位读写位置。seek函数格式:seek(offset)with自动管理文件,执行完毕后自动关闭文件,避免手动操作和资源泄露。7.1.2文本文件的读写7.1.2文本文件的读写第7章文件处理7.1文本文件的读写3.​关闭文件文件操作完成后必须调用close()关闭文件,否则可能导致:(1)资源占用文件描述符耗尽:每次open()调用都会占用一个文件描述符(系统用于标识文件的非负整数),当达到系统上限时将无法打开新文件并抛出OSError。内存占用:每个打开的文件都会占用内存缓存数据,大量未关闭文件会累积消耗内存,导致性能下降甚至内存不足。(2)数据丢失Python写入文件时会使用缓冲区提升效率。调用write()时数据暂存缓冲区,仅当缓冲区满或文件关闭时才写入磁盘。若未正常关闭文件,程序崩溃或断电可能导致缓冲区数据丢失。(3)文件损坏文件元数据不一致:文件不关闭导致文件元数据(如大小、修改时间)无法正确更新,在系统异常时可能造成文件损坏。为确保文件并发访问安全,系统会对文件加锁。若未正常关闭文件,锁将无法释放,导致其他程序无法访问,可能引发数据冲突或文件损坏。(4)并发访问问题在多进程/线程环境中,未关闭文件可能导致访问冲突。例如,一个线程写入文件后未关闭,另一线程读取时可能获取不完整或错误数据,引发数据不一致问题。7.2.1bytes数据类型7.1.2文本文件的读写第7章文件处理7.2二进制文件的读写1.字符串与字节串的比较​字符串vs字节串:​​字符串:字符序列(可读文本)。字节串:字节序列(二进制数据,元素为0-255整数)。​2.创建bytes对象①字面量:​​s=b"Good"(仅限ASCII字符)。s=b"Good"#创建字节串print(s[0],s[-1]#利用索引输出字节串的第1个元素和最后1个元素#输出:70100#字符"G"、"d"的ASCII值分别为70、100②使用

bytes类的构造函数创建bytes对象:​​bytes():创建空字节串。bytes(n):创建长度为n的全0字节串。bytes(iterable):从可迭代对象创建。bytes(string,encoding):按编码转换字符串。s="不到长城非好汉"print(s.encode() #输出字符串的UTF-8编码print(s.encode("GBK") #输出字符串的GBK编码③使用字符串对象的

encode方法创建

bytes

对象【练一练】仿效上例方法输出全部英文字母和数字的ASCII码值。【例7.7】【例7.8】7.2.1bytes数据类型7.1.2文本文件的读写第7章文件处理7.2二进制文件的读写3.将

bytes

对象转换为字符串使用

bytes

对象的

decode方法可将字节串解码为字符串。decode方法的语法格式:参数说明:encoding指定使用的编码方式;errors指定无法解码时的处理方式,默认值为'strict'(抛出异常)。也可设置为'ignore'(忽略错误,不作处理)和'replace'(使用字符'?'替换无法解码的字符)。s="岩松立壁迎霜劲,翠竹凌霜傲雪坚"b=s.encode()#按UTF-8编码将字符串转换为字节串s=b.decode()#按UTF-8编码对字节串进行解码,得到字符串sprint(s)#因编码与解码方式相同,能正常输出s=b.decode("ANSI")#对字节串b按ANSI解码,会出现乱码print(s)#输出的是乱码【例7.9】decode(encoding='utf-8',errors='strict')7.2.2二进制文件的读写第7章文件处理7.2二进制文件的读写1.文件打开模式open函数默认使用文本模式。对于二进制文件,必须使用二进制模式打开,即在原文本模式的基础上添加字符

'b'。如

'rb'(二进制只读)、'wb+'(二进制读写写)等。

二进制文件读写的数据是

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论