生活中的 Python

178 阅读8分钟

「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战」。

前言

Python 一直以简单著称,也是许多非计算机专业人士首选的学习语言。但是 Python 真的有那么神奇吗,其实 Python 确实能简化日常中的许多工作,本次 Chat 的目的就是分享 Python 在日常生活中的一些应用。

文件遍历操作

文件遍历操作在本文中使用的比较多,因此我们先介绍一下文件遍历的操作。在 Python 中提供了 os 模块进行系统操作,其中文件目录操作就封装在了这个模块。下面我们来看看 os.listdir 和 os.walk 两个函数。

os.listdir

os.listdir 的作用是获取指定目录下所有文件或文件夹,它不区分文件文件夹,会直接给我们返回一个字符串列表。示例代码如下:

import os
# 要获取文件或文件夹的目录
basedir = "test"
# 调用 listdir
files = os.listdir(basedir)
print(files)

输出结果如下:

test1
test2
test.py
test.txt

可以看到,它输出的 test 目录下的文件夹和文件。这里需要注意,如果 test1 文件夹下还有子文件,os.listdir 不会输出。

os.walk

os.listdir 使用起来非常简单,但是比较有局限,如果我们想要遍历所有文件,包括子文件的话就需要使用 os.walk 函数。示例代码如下:

import os
# 要遍历的目录
basedir = "test"
# 遍历目录
for root, dirs, files in os.walk(basedir):
	for file in files:
		print(root, file)

我们通过上面的代码可以获取 test 目录下所有文件,包括子文件。输出效果如下:

.test test.py
.test test.txt
.test\test1 test.txt

可以看到子文件也输出了。不过我们想要读取文件要拼接一个合法的路径,这就可以用到 os.path.join 函数了。具体使用如下:

import os

basedir = "test"
for root, dirs, files in os.walk(basedir):
    for file in files:
        path = os.path.join(root, file)
        print(path)

它接收两个字符串,分别是目录和文件,它会根据不同的操作系统拼接不同的连接符。输出效果如下:

test\test.py
test\test.txt
test\test1\test.txt

现在我们已经知道了文件的目录的遍历,可以开始学习下面的内容了。

删除空文件夹

删除空文件夹的操作非常简单,这里需要用到几个函数。我们先来看看:

# 判断路径是否是文件夹
os.path.isdir(path)
# 删除文件夹
os.rmdir(path)

这里我们可以用 os.path.isdir,也可以不用,这里我们不用。

除了上面的操作,我们还需要判断是否是空文件夹,这就可以使用 os.listdir 函数了。如果是空文件夹它就会返回一个列表,因此删除空文件夹的操作可以写成如下:

import os
basedir = "test"
for root, dirs, files in os.walk(basedir):
	for dir in dirs:
		path = os.path.join(root, dir)
		# 如果是空文件夹
		if not os.listdir(path):
			# 删除该文件夹
			os.rmdir(path)

这样我们就实现了空文件夹的删除。

查找最近修改过的文件

这里同样是要用到遍历操作,我们可以通过 os.stat 查看文件的一些属性,包括最后一次修改时间,我们可以通过这个属性找到最近修改过的文件。具体代码如下:

import os
import time
# 获取当前的秒数
current = time.time()
basedir = "D:\\"

# 遍历文件夹
for root, dirs, files in os.walk(basedir):
    for file in files:
        path = os.path.join(root, file)
        # 获取文件属性
        sta = os.stat(path)
		
		# 如果文件最后修改时间和当前时间差小于 60,说明最近一分钟修改过
        if current - sta.st_mtime < 60:
            print(path, "最近一分钟修改过")

上面的代码很好理解,我们来看看 os.stat 返回的内容:

os.stat_result(st_mode=33206, st_ino=562949953543119, st_dev=275139486, st_nlink=1, st_uid=0, st_gid=0, st_size=2314, st_atime=1614868173, st_mtime=1559622542, st_ctime=1614868173)

可以看到有很多属性,这里我们只使用了 st_mtime,也就是最近修改时间。

生成图片缩略图

生成缩略图需要使用到我们的第三方模块 Pillow,按照方式如下:

pip install pillow

安装完成我们就可以使用了。Pillow 中有很多图片相关的操作,这里只使用生成缩略图的操作:

import os
from PIL import Image

basedir = "test"
save_dir = "test_thum"
# 创建文件夹用于保存缩略图
if not os.path.exists(save_dir):
    os.mkdir(save_dir)

# 获取目录下图片,生成缩略图
for i, file in enumerate(os.listdir(basedir)):
    path = os.path.join(basedir, file)
    if path.endswith(".jpg"):
        img = Image.open(path)
        img.thumbnail((100, 200))
        img.save(save_dir + "/" + str(i) + ".jpg")

这里我们来看几点,首先是创建文件夹的操作:

# 创建文件夹用于保存缩略图
if not os.path.exists(save_dir):
    os.mkdir(save_dir)

我们先判断了文件夹是否存在,然后再创建,这样就不需要手动创建这个文件夹了。

然后是读取图片并生成缩略图的操作:

img = Image.open(path)
img.thumbnail((100, 200))
img.save(save_dir + "/" + str(i) + ".jpg")

这里先用 Image.open 读取图片,然后调用图片对象的 thumbnail 方法,传入缩略图的长宽元组。这里需要注意一点,我们生成的缩略图不会进行形变,而是直接缩小。

然后调用 save 方法保存缩略图。

添加图片水印

这里我们依然是使用 Pillow 模块,这里主要是使用 paste 方法在原图上粘贴水印。具体代码如下:

from PIL import Image
# 读取原图
img = Image.open("test.png").convert("RGBA")
# 读取水印图片
logo = Image.open("logo.jpg").convert("RGBA")
# 分离通道
r, g, b, a = logo.split()
# 将水印粘贴到原图左上角(0, 0)位置
img.paste(logo, (0, 0), mask=a)
img.show()

这里可以看到,我们在读取图片后调用了 convert 函数,转换成“RGBA”的图片,这是为了防止丢失透明图的透明通道,然后调用 img.paste 方法粘贴水印,这里第一个参数是被粘贴的图片,第二个参数是位置,第三个参数不是必须的。但是如果是透明图片,想有透明效果,就要将被粘贴图片的透明通道传过来。也就是前面 split 分离出的 a。

获取 GIF 的图片帧

获取 GIF 图片帧同样需要使用第三方模块,这里使用 opencv,安装方式如下:

pip install opencv-python

安装完成后我们可以调用其中的 cv2.VideoCapture 函数,它可以用来调用摄像头,也可以读取视频或动图,这里我们调用动图:

import cv2
cap = cv2.VidepCapture("1.gif")
name = 0
while True:
	ret, frame = cap.read()
	if not ret:
		break
	cv2.imwrite(str(name) + ".jpg", frame)
	name += 1

这里我们主要来看 cap.read 方法,它会返回两个参数,第一个是是否有下一帧,如果没有下一帧我们就跳出循环。第二个则是图片帧,我们将 frame 写入到文件当中,这样我们就完成了 GIF 图片的逐帧读取。

视频转 GIF 和截取 GIF 图

这里我们又要用到一个第三方模块 moviepy,安装方式如下:

pip install moviepy

moviepy 是视频剪辑的一大利器,这里我们只用来截取 GIF 图,操作如下。

from moviepy.editor import *
# 剪辑视频的 50-60 秒
clip = VideoFileClip('test.mp4').subclip(50, 60)
# 保存成 gif
clip.write_gif("1.gif")

上面的操作非常简单,首先是用 VideoFileClip 读取视频,然后调用 subclip 函数剪辑视频,剪辑 GIF 也算一样的,然后我们将剪辑好的片段写成 GIF 图片。

解压压缩包中指定文件

解压文件是我们比较常用的操作,在 Python 中也提供了解压模块。这里我们用 zipfile 为例,使用非常简单:

from zipfile import ZipFile
# 打开压缩文件
f = ZipFile("test.pptx")
# 查看压缩包所有文件
for file in f.namelist():
    print(file)
# 关闭压缩包文件
f.close()

我们可以通过上面的方式读取压缩包中的所有文件。在能读取文件后,我们就能选择性解压文件了,比如只解压图片,那么我们的代码应该修改为如下:

import os
from zipfile import ZipFile
# 解压目录
unzip_path = "unzip"
# 如果解压目录不存在则创建
if not os.path.exists(unzip_path):
    os.mkdir(unzip_path)
with ZipFile("test.zip") as f:
    for file in f.namelist():
    	# 如果是图片则解压
        if file.endswith(".jpg"):
            f.extract(file, path=unzip_path)

上面我们在遍历文件是判断了是否是图片,然后嗲用 extract 方法来解压文件。

提取 PPT 中的图片

其实提取 PPT 中的图片操作非常简单,和上面解压指定文件是差不多的。因为 PPT 本身是一个压缩包,它的媒体文件存放在指定目录我们只需要筛选一下,就能实现 PPT 图片的提取,具体代码如下:

import os
from zipfile import ZipFile
unzip_path = "unzip"
if not os.path.exists(unzip_path):
    os.mkdir(unzip_path)
with ZipFile("test.pptx") as f:
    for file in f.namelist():
        if file.startswith("ppt/media/") and file.endswith(".jpg"):
            f.extract(file, path=unzip_path)

这里我们只是把筛选条件换了,其它都是一样的。这样我们就实现了 PPT 图片的提取。

其实 Python 还有很多应用,只要肯发掘,一定可以找到很多有趣的操作。


本文首发于 GitChat,未经授权不得转载,转载需与 GitChat 联系。