模块与包
模块与包在 Python 当中使用得不可谓不频繁,Python 之所以代码量少、开发速度快,模块与包占据了非常大的原因,这也是进阶爬虫、数据分析、web 开发等方向必须掌握的技能。
模块
模块指的是 Python 的程序文件(源文件),模块的文件名就是模块名加上.py,里面包含了 Python 对象定义和 Python 语句,模块包含了定义函数、类和执行代码等等,一般情况下不要去修改模块,以免模块失效。
Python 中允许导入的形式来进行模块调用,Python 中的模块也是对象,模块中定义的所有全局变量,导入后都成为模块的属性。
如果要导入多个模块,可以只用 1 个 import 来导入多个模块,多个模块之间用逗号隔开即可,但是在 Python 的 PEP8 风格里面,不建议这么做,所以要导入几个模块,就写几个 import 来进行挨个导入。
例子:导入 math 模块并调用 sqrt () 开平方的功能对 9 进行开平方
import math
num = math.sqrt(9)
print(num)
输出结果:
3.0
在 Python 中进行运算操作默认返回的是 float 类型,所以是 3.0。
from math import sqrt
num = sqrt(9)
print(num)
输出结果:
3.0
模块定义别名
有的模块或者模块内的功能名字比较长,多次使用的时候不方便,可以进行自定义模块或者功能的名字。
模块自定义别名: import 模块名 as 别名
from 模块名 import 功能名 as 别名
自定义模块
每个人都能生成自定义模块来进行调用,自定义模块就是 Python 文件,写代码时创建的 Python 文件就相当于 1 个模块。
注意点:被调用的模块尽量放在当前 Python 文件相同目录下,否则导入时要声明所在文件夹才能导入。
例子:自定义 1 个模块,在另一个 Python 文件中进行调用。
新建 1 个名为 module1 的 Python 文件,代码如下:
def fun1(a,b) :
print(a+b)
相同目录下新建另一个 Python 文件,调用 module1.py 这个模块:
import module1
module1.fun1(20,30)
运行当前 Python 文件结果:
50
模块的测试
每个模块导入的时候都默认被执行一遍,但同时在模块内部又存在着很多的内部测试代码,为了避免导入模块时执行了模块内部的测试代码,于是就牵扯到一个方法:
很多模块在内部都有测试方法:
if __name__ == "__main__":
代码1
这个方法能够实现一个功能,在模块中执行的话,就会执行代码 1 的代码,在其他文件导入该模块的时候,则不会执行代码 1 的代码,所以一般模块内部的测试都放在了代码 1 当中。
为什么?神奇的点就在于__ name __ ,它在当前文件中执行的结果是 __ main__,在其他文件导入时执行的结果是模块名,所以利用这一点,用上 if 语句就能判断模块执行到底是在当前文件执行还是被导入执行。
举例:
新建 1 个 Python 叫 module1,作为模块,代码如下:
print(__name__)
执行结果:
__main__
再新建 1 个 Python 文件,导入刚才建好的 module1.py 模块:
import module1
执行结果:
module1
在当前文件的执行和被导入时执行,结果是不一样的,所以它成为了模块的内部测试方法。
注意点:在自定义的模块中,不建议写 while 循坏,不然导入的过程中一直在执行模块里面的 while 循坏,可能会跳不出来,也就是一直在导入模块,其他代码执行不到。
包
包就是将有联系的模块放在同一个文件夹下,并且该文件夹里有“init.py”这个文件,这个文件夹就叫做包。
包的特征:
1.包也是对象
2.必须有__init__.py文件
3.__init__.py文件是包的构造方法,控制着包的导入行为,一般是个空包
4.包里面不仅可以有模块,还可以有子包
包的导入
常规导入方法主要有 2 种。
方法 1:import 包名.模块名.目标
方法 2:import 包名.子包.模块名.目标
包的使用
import 包名.模块名
包名.模块名.功能
import demo.my_module
print(demo.my_module.a)
demo.my_module.fun1()
----------------
from 包名 import 模块名
模块名.功能
模块名.变量
from demo import my_module
print(my_module.a)
my_module.fun1()
----------------
import 包名.模块名 as 别名
别名.功能
别名.变量
import demo.my_module as n1
print(n1.a)
n1.fun1()
----------------
from 包名.模块名 import 功能1
功能1
from demo.my_module import fun1
fun1()
----------------
def fun1():
print("这是功能1")
def fun2():
print("这是功能2")
from demo.hhhh import *
fun1()
fun2()
模块与包的作用
-
提高代码的可重用性。好用的代码不止你 1 个人可以用,很多人都可以重复使用它。 -
提高代码的可读性。如果所有的代码都放在 1 个.py 文件中,那代码就太长了,增加了理解和维护难度,所以可以把一些常用的代码封装成包和模块,起 1 个望文生义的名字,需要的时候直接用就行,减少了代码的数量,提高了可读性。 -
减少代码的冗余。模块里面封装的一些方法,我们直接给参数去使用就可以了,不用把方法再写一遍,占用内存,也就减少了代码的冗余。
文件操作
计算机中的文件通常是指计算机硬盘为载体的、存储在计算机中的信息集合,主要的表现形式为视频、音频、图片以及文档四类,比如执行性文件.exe、文档文件.txt、网页文件.html 等等。
在现实中,我们对文件进行操作可以大致总结为 “打开→操作(阅读、删除、修改等)→保存→关闭”,在 Python 当中依然是如此。
open(name,mode) ---- 打开文件
这是 Python 打开文件的方法,用于打开一个文件,返回的是一个文件对象。
name 指的是文件名,一定要写全,何为写全?就是要写清楚 存储路径 + 文件名 + 后缀 。
为何要写这么全?因为就算是相同的存储路径下,文件名相同的文件也可能不止一个,只要后缀不一样,计算机是允许存在同名文件,所以不写全的话,计算机是不知道你指的是谁
mode 是打开文件的模式,默认是 r,也就是只读的方式。mode 的方式有很多,比如读、写等等。
write (“内容 ") ------ 写
顾名思义,就是向文件对象中写入内容。
read() ------- 读
向文件中写入内容,括号里面可以写数字也可以不写,不写的话默认是读取全部内容,写数字则表示读取 X 个字符,比如说 read (6) 则读取文件对象的 6 个字符。
close() ------ 关闭文件
关闭文件的方法,如果你在进行文件操作之后不进行关闭文件,则文件一直处于打开和操作的状态,会占用内存。
file 的对象方法
文件的方法有很多,比如 read () 和 write (),还有一些常用的方法需要掌握:
1. close()
关闭文件---非常重要
2. read([count])
读取文件中的内容
count:字节数量
3. readlines()
读取所有内容,打包成列表
4. readline()
读取一行数据,追加读取,读取过的不能再次读取
5. seek(offset,[from])
修改指针的位置:从from位置移动了offset个字节
from:0则表示从起始位置,1则表示从当前位置开始,2则表示从末尾开始
oofset:要移动的字节数
6. write()
向文件中写入内容
os 模块是一个用于访问操作系统的模块,在进行文件操作的时候常会用到它。模块在使用之前要进行导入。
import os
os.rename(原文件名,新的文件名) ——文件重命名
os.remove(文件名) ——删除文件
如果不说明路径,则在源代码所在文件夹下寻找,寻找不到会报错。
若想删除指定文件夹下的文件,文件名则需要具体路径,例如 os.remove(r"D:\test_1\文件名"),r防止斜杠发生转义
os.mkdir(文件夹名) ——创建文件夹
os.rmdir(文件夹名) ——删除文件夹
os.getced() ——获取当前目录
os.chdir(目录) ——切换目录
os.listdir(目录) ——获取当前文件夹下所有的文件或者文件夹,返回一个列表
os.listdir("aa")
异常处理
try-except
它能够将可能出错的代码进行处理,处理后报错的红色字体将会转换成简短的、正常的字体。
try:
有可能出现异常的代码
except 异常类型 as 变量
处理后的代码
tyr-except 并不影响代码的运行,如果你的代码没有报错,你就算是写了 tyr-except,它也只会执行 try 那行代码,那行代码没有错误,那就不会执行 except 里面的代码。
try-except-except
这种方法和前面的 try-except 写法是差不多的,只是后面再增加了一个 except,可用于判断多种可能报错的情况。
try:
1 / 0
print(a)
except NameError as s:
print(s)
except ZeroDivisionError:
print("除数不能为0")
try-except-else
如果没有异常,则执行 else 里面的代码。
try:
a = 10
except (ZeroDivisionError,NameError) as ss:
print(ss)
else:
print(a)
try-except-finally
不管代码是否有异常,最后都会执行 finally 里面的代码。
try:
a = 10
1 / 0
except (ZeroDivisionError,NameError) as ss:
print(ss)
finally:
print("执行完毕")
顶层类 Exception
except 后面其实可以不加错误类型,因为系统会默认认为后面的错误是类型是 Exception,这是 1 个顶层类,包含了所有的出错类型。
try:
a = 10
1 / 0
except:
print("出错啦")
finally:
print("执行完毕")
正则表达式
正则作为处理字符串的一个实用工具,在 Python 中经常会用到,比如爬虫爬取数据时常用正则来检索字符串等等。正则表达式已经内嵌在 Python 中,通过导入 re 模块就可以使用。
导入 re 模块
在使用正则表达式之前,需要导入 re 模块。
import re
findall()的语法:
导入了 re 模块之后就可以使用 findall()方法了
findall(正则表达式,目标字符串)
findall()的是由正则表达式和目标字符串组成,目标字符串就是你要检索的东西。使用 findall()之后返回的结果是一个列表,列表中是符合正则要求的字符串
正则表达式常用元字符在此不再讲解
正则对象的使用方法
正则对象的使用方法不仅通过 findall () 来使用,还可以通过其他的方法进行使用,效果是不一样的,这里我做个简单的总结:
(1)findall() 找到 re 匹配的所有字符串,返回一个列表
(2)search() 扫描字符串,找到这个 re 匹配的位置(仅仅是第一个查到的)
(3)match() 决定 re 是否在字符串刚开始的位置(匹配行首)
Match object 的操作方法
Match 对象常见的使用方法有以下几个:
(1)group() 返回 re 匹配的字符串
(2)start() 返回匹配开始的位置
(3)end() 返回匹配结束的位置
(4)span() 返回一个元组:(开始,结束)的位置
re 模块的函数
findall() 根据正则表达式返回匹配到的所有字符串,这个我就不多说了,前面都是在介绍它。
sub (正则,新字符串,原字符串) sub () 函数的功能是替换字符串
subn (正则,新字符串,原字符串) subn () 的作用是替换字符串,并返回替换的次数
split() split () 分割字符串
|