了解异常的概念。
先打开软件,创建一个名为“09_Python的异常、模块与包”的文件夹,并创建一个名为“01_演示异常的出现”的py文件。
然后主动写一段 ! ! 错误 ! ! 代码,演示异常的出现。
"""
主动写一段错误代码,演示异常的出现
"""
# 通过open,读取一个不存在的文件
f = open("D:/abc.txt", "r", encoding="UTF-8")
知道为什么要捕获异常;掌握捕获异常的语法格式。
先打开软件,创建一个名为“02_异常的捕获”的py文件。
编写代码并运行两次(注:第二次运行时,根据代码,有的不存在的文件会被创建),对比两次的结果,并结合理解各种捕获异常的效果。代码如下,可参考注释进行理解。
"""
演示捕获异常
"""
# 基本捕获语法
try:
# 以只读模式打开不存在的文件abc.txt
f = open("D:/test/abc.txt", "r", encoding="UTF-8")
except:
# 如果出现错误,则进行捕获并执行except的代码
print("出现异常了,因为文件不存在,我将open的r模式,改为w模式去打开")
f = open("D:/test/abc.txt", "w", encoding="UTF-8")
# 捕获指定的异常
try:
# 1 / 0 #未正确设置捕获异常类型,将无法捕获异常
print(name)
except NameError as e: # 给这个错误取 别名 为 e
print("出现了变量未定义的异常")
print(e)
# 捕获多个异常
try:
# 1 / 0
print(name)
except (NameError, ZeroDivisionError) as e:
print("出现了变量未定义或者除以0的异常错误")
# 捕获所有异常
try:
# 1 / 0
# print(name)
f = open("D:/test/ab223c.txt", "r", encoding="UTF-8") # 以只读模式打开不存在的文件ab223c.txt
# print("Hello")
except Exception as e: # 或 except:
print("出现异常了")
else:
print("好高兴,没有异常。")
# finally 有没有异常都要执行
try:
f = open("D:/test/123.txt", "r", encoding="UTF-8") # 以只读模式打开不存在的文件123.txt
except Exception as e:
print("出现异常了")
f = open("D:/test/123.txt", "w", encoding="UTF-8")
else:
print("好高兴,没有异常。")
finally:
print("我是finally,有没有异常我都要执行")
f.close()
知道异常具有传递性;在了解异常具有传递性后,为了更方便快速地捕获异常,可以从高层次(如函数调用的最高层)中去捕获这个高层次调用含有异常的低层次的代码结构。
先打开软件,创建一个名为“03_异常的传递”的py文件。
如下所示,先编写多个函数互相进行调用,暂时不加异常的捕获,可以看到异常的传递性。代码如下,可参考注释进行理解。
"""
演示异常的传递性
"""
# 定义一个出现异常的函数
def func1():
print("fUnc1开始执行")
num = 1 / 0
# 肯定有异常,除以0的异常
print("func1结束执行")
# 定义一个无异常的函数,调用上面的函数
def func2():
print("func2开始执行")
func1()
print("fUnc2结束执行")
# 定义一个方法,调用上面的方法
def main():
func2()
main()
加上异常的捕获后的代码如下,运行后也能从运行结果上体现异常的传递性。
"""
演示异常的传递性
"""
# 定义一个出现异常的函数
def func1():
print("fUnc1开始执行")
num = 1 / 0
# 肯定有异常,除以0的异常
print("func1结束执行")
# 定义一个无异常的函数,调用上面的函数
def func2():
print("func2开始执行")
func1()
print("fUnc2结束执行")
# 定义一个方法,调用上面的方法
def main():
try:
func2()
except Exception as e:
print(f"出现异常了,异常的信息是:{e}")
main()
了解什么是模块;掌握导入Python内置的模块。
注:本图所示的语法中带中括号[]为可选项,即from、as可以不写,而import必须写。
创建一个名为“04_1_模块的导入”的py文件。
当程序写到一部分时,为了查看time模块,可按住Ctr不放,点击time,即可跳转到time中。然后,在time.py文件中可以看到函数sleep。
然后回到代码中,编写代码并运行。代码如下,可参考注释进行理解。可以体会“import 模块名”的用法。
"""
演示Python的模块导入
"""
# 使用import导入time模块,并使用time模块里的sleep功能(函数)
import time # 导入Python内置的time模块(即time.py这个代码文件)
print("你好")
time.sleep(5) # 通过.就可以使用模块内部的全部功能(类、函数、变量)
print("我好")
如下重新编写代码并运行(使用快捷键Ctr+/可快速注释),体会“from 模块名 import 功能名”的用法。
"""
演示Python的模块导入
"""
# # 使用import导入time模块,并使用time模块里的sleep功能(函数)
# import time # 导入Python内置的time模块(即time.py这个代码文件)
#
# print("你好")
# time.sleep(5) # 通过.就可以使用模块内部的全部功能(类、函数、变量)
# print("我好")
# 使用from导入time的sleep功能(函数)
from time import sleep
print("你好")
sleep(5)
print("我好")
如下重新编写代码并运行(使用快捷键Ctr+/可快速注释),体会“from 模块名 import *”的用法。
"""
演示Python的模块导入
"""
# # 使用import导入time模块,并使用time模块里的sleep功能(函数)
# import time # 导入Python内置的time模块(即time.py这个代码文件)
#
# print("你好")
# time.sleep(5) # 通过.就可以使用模块内部的全部功能(类、函数、变量)
# print("我好")
# # 使用from导入time的sleep功能(函数)
# from time import sleep
#
# print("你好")
# sleep(5)
# print("我好")
# 使用*导入time模块的全部功能
from time import * # *表示全部的意思
print("你好")
sleep(5)
print("我好")
如下重新编写代码并运行(使用快捷键Ctr+/可快速注释),体会as给模块取别名的用法。
"""
演示Python的模块导入
"""
# # 使用import导入time模块,并使用time模块里的sleep功能(函数)
# import time # 导入Python内置的time模块(即time.py这个代码文件)
#
# print("你好")
# time.sleep(5) # 通过.就可以使用模块内部的全部功能(类、函数、变量)
# print("我好")
# # 使用from导入time的sleep功能(函数)
# from time import sleep
#
# print("你好")
# sleep(5)
# print("我好")
# # 使用*导入time模块的全部功能
# from time import * # *表示全部的意思
#
# print("你好")
# sleep(5)
# print("我好")
# 使用as给特定功能加上别名
import time as t
print("你好")
t.sleep(5)
print("我好")
如下重新编写代码并运行(使用快捷键Ctr+/可快速注释),体会as给功能取别名的用法。
"""
演示Python的模块导入
"""
# # 使用import导入time模块,并使用time模块里的sleep功能(函数)
# import time # 导入Python内置的time模块(即time.py这个代码文件)
#
# print("你好")
# time.sleep(5) # 通过.就可以使用模块内部的全部功能(类、函数、变量)
# print("我好")
# # 使用from导入time的sleep功能(函数)
# from time import sleep
#
# print("你好")
# sleep(5)
# print("我好")
# # 使用*导入time模块的全部功能
# from time import * # *表示全部的意思
#
# print("你好")
# sleep(5)
# print("我好")
# # 使用as给特定功能加上别名
# import time as t
#
# print("你好")
# t.sleep(5)
# print("我好")
from time import sleep as sl
print("你好")
sl(5)
print("我好")
了解如何自定义模块并使用;了解__main__变量的作用。
创建一个名为“04_2_自定义模块”的py文件,一个名为“my_module1”的py文件作为自定义的模块1,一个名为“my_module2”的py文件作为自定义的模块2。
编写代码模块1(即my_module1.py文件)的代码。
def test(a, b):
print(a + b)
def test(a, b):
print(a - b)
在本次使用的文件(即04_2_自定义模块.py文件)中编写代码并运行,体会模块调用以及当调用不同模块的具有相同功能名的函数,后面模块的函数会覆盖前面模块的函数的现象。
"""
演示自定义模块
"""
# 导入自定义模块使用
# import my_module1
#
# my_module1.test(1, 2)
from my_module1 import test
test(1, 2)
# 导入不同模块的同名功能
from my_module1 import test
from my_module2 import test
test(1, 2)
在编写完模块代码后,往往需要对它进行测试,比如需要对my_module1.py文件进行测试,在里面加了一行“test(1,2)”的代码。(框里为my_module1.py文件修改后的代码)
def test(a, b):
print(a + b)
test(1, 2)
回到本次使用的文件(即04_2_自定义模块.py文件),使用快捷键Ctr+/将其他内容注释,然后写上仅仅导入my_module1.py模块的代码,代码如下,然后再运行,发现也会运行my_module1.py中的测试代码test(1, 2)。
"""
演示自定义模块
"""
# 导入自定义模块使用
# import my_module1
#
# my_module1.test(1, 2)
# from my_module1 import test
#
# test(1, 2)
#
# # 导入不同模块的同名功能
# from my_module1 import test
# from my_module2 import test
#
# test(1, 2)
# __main__变量
from my_module1 import test
回到my_module1.py模块的代码中,如果我们不舍得删除测试代码test(1, 2),就可以使用变量__main__,然后就能解决问题,如下几张图所示。这是因为__name__为内置变量,当运行含有“if name == ‘main’:”的判断语句的py文件时,它会将它(即__name__)设为’main’,而在别的py文件中调用这个py文件的某些功能时,它(即__name__)就不再是’main’了。因此,这样就实现了测试代码不用删除,在模块中能运行测试代码,而在导入模块时也不会执行模块中的测试代码了。(框里为my_module1.py文件修改后的代码)
def test(a, b):
print(a + b)
if __name__ == '__main__':
test(1, 2)
然后,我们在两个文件my_module1.py、04_2_自定义模块.py中运行一下,可以发现上述效果已经实现。
然后修改模块2(即文件my_module2.py)的代码如下。
def test(a, b):
print(a - b)
def test_a(a, b):
print(a + b)
def test_b(a, b):
print(a - b)
再修改名为“04_2_自定义模块”的py文件的代码,并运行,可以发现“from my_module2 import *”导入后,所有功能均可运用。
"""
演示自定义模块
"""
# 导入自定义模块使用
# import my_module1
#
# my_module1.test(1, 2)
# from my_module1 import test
#
# test(1, 2)
#
# # 导入不同模块的同名功能
# from my_module1 import test
# from my_module2 import test
#
# test(1, 2)
# # __main__变量
# from my_module1 import test
# __all__变量
from my_module2 import *
print(f"test(1, 2)的结果:", end="")
test(1, 2)
print(f"test_a(1, 2)的结果:", end="")
test_a(1, 2)
print(f"test_b(2, 1)的结果:", end="")
test_b(2, 1)
然后回到模块2(即文件my_module2.py)的文件中,添加代码“all = [‘test_a’]”。再回到名为“04_2_自定义模块”的py文件中,发现只有test_a能使用,从中能体现变量__all__的作用。
了解什么是Python包;掌握如何自定义包。
创建一个名为“05_1_Python包”的py文件。
创建一个名为“my_package”的Python包(相比于普通的文件夹,Python包中含有文件__init__.py)。
在名为“my_package”的Python包中新建两个模块文件my_module1.py、my_module2.py,然后分别在这两个模块文件中编写相应的代码。包里的模块文件my_module1.py的代码如下框。
"""
演示自定义模块1
"""
def info_print1():
print("我是模块1的功能函数代码")
包里的模块文件my_module2.py操作一样,它的代码如下框。
"""
演示自定义模块2
"""
def info_print2():
print("我是模块2的功能函数代码")
回到文件“05_1_Python包.py”中,输入代码并运行,体会从Python包中如何导入对应的模块一种方式。
"""
演示Python的包
"""
# 创建一个包
# 导入自定义的包中的模块,并使用
import my_package.my_module1
import my_package.my_module2
# 调用
my_package.my_module1.info_print1() # 调用my_package包里的模块my_module1里的函数info_print1
my_package.my_module2.info_print2() # 调用my_package包里的模块my_module2里的函数info_print2
如下重新编写代码并运行(使用快捷键Ctr+/可快速注释),体会从Python包中如何导入对应的模块另一种方式。
"""
演示Python的包
"""
# 方式1
# # 创建一个包
# # 导入自定义的包中的模块,并使用
# import my_package.my_module1
# import my_package.my_module2
#
# # 调用
# my_package.my_module1.info_print1() # 调用my_package包里的模块my_module1里的函数info_print1
# my_package.my_module2.info_print2() # 调用my_package包里的模块my_module2里的函数info_print2
# 方式2
from my_package import my_module1
from my_package import my_module2
my_module1.info_print1()
my_module2.info_print2()
如下重新编写代码并运行(使用快捷键Ctr+/可快速注释),体会从Python包中如何导入某模块的某函数。
"""
演示Python的包
"""
# 方式1
# # 创建一个包
# # 导入自定义的包中的模块,并使用
# import my_package.my_module1
# import my_package.my_module2
#
# # 调用
# my_package.my_module1.info_print1() # 调用my_package包里的模块my_module1里的函数info_print1
# my_package.my_module2.info_print2() # 调用my_package包里的模块my_module2里的函数info_print2
# # 方式2
# from my_package import my_module1
# from my_package import my_module2
#
# my_module1.info_print1()
# my_module2.info_print2()
# 导入某包的某模块的某函数
from my_package.my_module1 import info_print1
from my_package.my_module2 import info_print2
info_print1()
info_print2()
为了看到变量’ all’对’from xxx import *'的影响,如下图,先修改文件__init__.py里面的内容,如下图所示。
__all__ = ['my_module1']
回到文件“05_1_Python包.py”中,输入代码并运行。
"""
演示Python的包
"""
# 方式1
# # 创建一个包
# # 导入自定义的包中的模块,并使用
# import my_package.my_module1
# import my_package.my_module2
#
# # 调用
# my_package.my_module1.info_print1() # 调用my_package包里的模块my_module1里的函数info_print1
# my_package.my_module2.info_print2() # 调用my_package包里的模块my_module2里的函数info_print2
# # 方式2:导入包的指定模块 from 包名 import 模块名
# from my_package import my_module1
# from my_package import my_module2
#
# my_module1.info_print1()
# my_module2.info_print2()
# # 方式3:导入某包的某模块的某函数 from 包名.模块名 import 功能名
# from my_package.my_module1 import info_print1
# from my_package.my_module2 import info_print2
#
# info_print1()
# info_print2()
# 通过__all__变量,控制 import *
from my_package import *
my_module1.info_print1()
# my_module2.info_print2()
然后取消图中所示那一行的代码,运行报错,即可说明变量’ all’对’from xxx import *'的影响,只能使用变量’ all’所指的模块。
了解什么是第三方包;掌握使用pip安装第三方包。
国内网站不止这一个,随便必应一下就能找到很多如下框(来源于知乎上的Krabs),能用,速度够快就行。
清华:https://pypi.tuna.tsinghua.edu.cn/simple
阿里云:http://mirrors.aliyun.com/pypi/simple/
中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
华中理工大学:http://pypi.hustunique.com/
山东理工大学:http://pypi.sdutlinux.org/
豆瓣:http://pypi.douban.com/simple/
本小点将演示如何使用pip命令安装名为“numpy”的Python包。如下几张图所示(方法不唯一),打开“命令提示符”。
然后在联网的条件下,按照“pip install 第三方包的名字”的格式,输入“pip install numpy”后,并按Enter键。
我们会发现下载速度非常慢,这是由于pip程序默认连接的是国外的网站,所以在国内连接起来速度就非常慢。
为了让下载速度更快,可以通过命令让其连接国内的网站进行包的安装,如下图所示,输入“pip install -i https://pypi.tuna.tsinghua.edu.cn/simple numpy”后按Enter键,然后会显示“Successfully”安装成功的提示。
然后如下图所示,输入“python”进入python中,然后输入“import numpy”没报错就说明下载成功。
这里以安装pandas包为例进行演示。首先,如图所示,在PyCharm右下角点击“解释器的设置”。
接着,如下图所示操作就OK了。
一些b站网友和我一样,下载包时报错(忘截图了),本人按一些网上给出的方法试了好几个都不行。回到PyCharm后,再试了一阵,发现将下载链接由清华源改成豆瓣源就没问题了(-i http://pypi.douban.com/simple/)。
打开软件,创建一个名为“06_综合案例练习”的py文件。
创建“my_utils”包,在包内创建2个模块:str_util.py和file_util.py。
如下编写模块str_util.py的代码,并运行测试一下。
"""
字符串相关的工具模块
"""
def str_reverse(s):
"""
功能: 将字符串完成反转操作
:param s: 将被反转的字符串
:return: 反转后的字符串
"""
return s[::-1] # 利用切片反着取,形成一个新的字符串,并返回
def substr(s, x, y):
"""
功能: 按照给定的下标完成给定字符串的切片
:param s: 即将被切片的字符串
:param x: 切片的开始下标
:param y: 切片的结束下标
:return: 切片完成后的字符串
"""
return s[x:y]
if __name__ == '__main__':
print(str_reverse("黑马程序员"))
print(substr("黑马程序员", 1, 3))
如下编写模块file_util.py的部分代码,先使用先前的文件“bill.txt”测试函数print_file_info的功能。
"""
文件处理相关的工具模块
"""
def print_file_info(file_name):
"""
功能: 将给定路径的文件内容输出到控制台中
:param file_name: 即将读取的文件路径
:return: None
"""
f = None # 设置初始值
try:
f = open(file_name, "r", encoding="UTF-8")
content = f.read()
print("文件的全部内容如下:")
print(content)
except Exception as e:
print(f"程序出现异常了,原因是:{e}")
finally:
if f: # 如果变量是None,表示False,就不执行关闭文件的操作;如果有任何内容,就是True,就执行关闭文件的操作
f.close()
if __name__ == '__main__':
print_file_info("D:/test/bill.txt")
先查看电脑里的路径D:\test,确保没有文件test_append.txt。然后继续完编写模块file_util.py的代码,测试函数append_to_file的功能。
"""
文件处理相关的工具模块
"""
def print_file_info(file_name):
"""
功能: 将给定路径的文件内容输出到控制台中
:param file_name: 即将读取的文件路径
:return: None
"""
f = None # 设置初始值
try:
f = open(file_name, "r", encoding="UTF-8")
content = f.read()
print("文件的全部内容如下:")
print(content)
except Exception as e:
print(f"程序出现异常了,原因是:{e}")
finally:
if f: # 如果变量是None,表示False,就不执行关闭文件的操作;如果有任何内容,就是True,就执行关闭文件的操作
f.close()
def append_to_file(file_name, data):
"""
功能: 将指定的数据追加到指定的文件中
:param file_name: 指定的文件的路径
:param data: 指定的数据
:return: None
"""
f = open(file_name, "a", encoding="UTF-8")
f.write(data)
f.write("\n") # 有一个换行符,保证下次追加时,首字不是紧贴着上次的内容,而是有一个换行隔开
f.close()
if __name__ == '__main__':
# print_file_info("D:/test/bill.txt")
append_to_file("D:/test/test_append.txt", "黑马程序员")
"""
演示异常、模块、包的综合案例练习
"""
# 创建my_utils包, 在包内创建:str_util.py和file_util.py 2个模块,并提供相应的函数
import my_utils.str_util
from my_utils import file_util
print(my_utils.str_util.str_reverse("黑马程序员"))
print(my_utils.str_util.substr("itheima", 0, 4))
print("未追加时", end="")
file_util.print_file_info("D:/test/test_append.txt")
file_util.append_to_file("D:/test/test_append.txt", "itheima")
print("追加后", end="")
file_util.print_file_info("D:/test/test_append.txt")
好了,本章的笔记到此结束,谢谢大家阅读。