Home | 简体中文 | 繁体中文 | 杂文 | Github | 知乎专栏 | Facebook | Linkedin | Youtube | 打赏(Donations) | About
知乎专栏

第 2 章 Library

目录

2.1. 文件和目录
2.1.1. 创建文件
2.1.2. 读取文件
2.1.3. 写入文件
2.1.4. 读取二进制文件
2.1.5. 文件名/扩展名
2.1.6. 创建目录
2.1.7. 权限判断
2.1.8. 判断文件/路径是否存在
2.1.9. 路径拼接
2.1.10. 目录和文件列表
2.1.11. os.scandir 扫描目录
2.1.12. 删除文件或目录
2.1.13. 路径操作
2.1.14. 复制文件
2.2. 随机数
2.2.1. 随机选择列表
2.2.2. 指定随机数范围
2.2.3. 指定随机数范围(整数)
2.2.4. 指定随机数范围(小数)
2.2.5. 打乱列表顺序
2.3. 进程与线程
2.3.1. subprocess
2.3.2. Python 多线程
2.3.3. 守护进程(Daemon)
2.4. 日志
2.4.1. logging
2.4.2. syslog
2.4.3. 日志彩色输出
2.5. 网络开发(Socket)
2.5.1. SimpleHTTPServer
2.5.2. UDP
2.5.3. Websocket
2.5.4. Network
2.6. YAML
2.6.1. 严格按段落展示 |、|+、|-
2.6.2. >、>+、>-
2.6.3. PyYAML
2.6.4. ruamel.yaml
2.7. Requests
2.8. httpx
2.8.1. 安装 https
2.8.2. 操作演示
2.8.3. 上传文件
2.8.4. Restful CRUD 操作
2.8.5. HTTP 2
2.8.6. BasicAuth
2.8.7. 异步请求
2.8.8. 日志输出
2.9. asyncio
2.9.1.
2.10. 终端环境开发
2.10.1. 命令行参数处理
2.10.2. getopt – Command line option parsing
2.10.3. ANSI Color
2.10.4. 进度条
2.10.5. texttable - module for creating simple ASCII tables
2.10.6. prompt_toolkit
2.10.7. Simple Terminal Menu
2.10.8. picotui
2.10.9. TUI
2.11. 验证码
2.11.1. 基本用法
2.11.2. Image CAPTCHAs
2.12. dbm Key-Value 数据库
2.13. keyboard
2.13.1. 读取键盘值
2.13.2. 功能键
2.13.3. 上下索道缆车开关门
2.14. GPS
2.14.1. gpsdclient
2.14.2. Traccar
2.15. ZeroRPC
2.16. fuse-python.x86_64 : Python bindings for FUSE - filesystem in userspace
2.17. Python-spdylay - Spdylay Python Extension Module
2.18. mechanize
2.19. python-memcached
2.20. python-subversion

2.1. 文件和目录

2.1.1. 创建文件

			
import time

logfile = time.strftime("netkiller-%Y-%m-%d.log",time.localtime());
f = open(logfile,mode="a+")

f.write(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) + " DEBUG "+"== Begin ==\r\n")
# 业务逻辑
f.write(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) + " INFO "+"Hello world!!!\r\n")
# 业务逻辑
f.write(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()) + " DEBUG "+"== End ==\r\n")

# 任务完成
f.flush()
f.close()			
			
		

2.1.2. 读取文件

		
f = open('/tmp/workfile', 'r+')
f.write('0123456789abcdef')
f.seek(5)     # Go to the 6th byte in the file
f.read(1)
f.seek(-3, 2) # Go to the 3rd byte before the end
f.read(1)
f.readline()
f.close()
		
		
			
for line in open("myfile.txt"):
    print line

with open("myfile.txt") as f:
    for line in f:
        print line
			
		

2.1.3. 写入文件

		
name = "Alice"
age = 30
with open('profile.txt', 'w') as file:
    file.write(f"Name: {name}\n")
    file.write(f"Age: {age}\n")		
		
		

utf-8 编码

		
with open('example.txt', 'w', encoding='utf-8') as file:
    file.write("你好,世界!")	
		
		

2.1.4. 读取二进制文件

			
with open('beak', 'rb+') as f:
    content = f.read()
    f.seek(0)
    f.write(content.replace(b'\r', b''))
    f.truncate()
			
		

2.1.5. 文件名/扩展名

2.1.5.1. 获取文件名

使用os.path.basename()获取文件名

			
import os

# 定义一个文件路径
file_path = "/home/user/documents/example.txt"

# 使用os.path.basename()获取文件名
file_name = os.path.basename(file_path)

print(file_name)  # 输出: example.txt			
			
			

2.1.5.2. 分割路径与文件名

			
# 返回值为元组 ('/Users/netkiller/Desktop', 'neo.txt')
path, name = os.path.split(file_path)			
			
			

2.1.5.3. 获取扩展名

			
import os

# 定义一个文件路径
file_path = "/home/user/documents/example.txt"

# 使用os.path.splitext()获取文件名和扩展名
file_name, file_extension = os.path.splitext(file_path)

print("文件名:", file_name)  # 输出: 文件名: /home/user/documents/example
print("扩展名:", file_extension)  # 输出: 扩展名: .txt	

file_extension = file_extension[1:]  # 去掉点号
print("去掉点号的扩展名:", file_extension)  # 输出: 去掉点号的扩展名: txt		
			
			
			
import os
ext = os.path.splitext("path/to/file.ext")[-1][1:]
print(ext)
			
			

			
path = "path/to/file.ext"
suffix = path.split(".")[1]
print("suffix: {}".format(suffix))			
			
			
			
import re

filename = "example.txt"
extension = re.findall(r"\.[^.]*$", filename)[0]
print(extension)			
			
			
			
filename = "myfile.txt"

extension = filename.rsplit(".", 1)[1]

print(extension)  # 输出:".txt"			
			
			

2.1.6. 创建目录

创建一层目录

		
dir_name = "neo"
if not os.path.exists(dir_name):
    os.mkdir(dir_name)
		
		

递归创建目录

		
os.makedirs('./path/path2/path3')

if not os.path.exists(saveDir):
    os.makedirs(saveDir)
		
		

使用默认权限创建目录,如果目录已存在,则不会引发异常

		
os.makedirs(output_folder, exist_ok=True)		
		
		

2.1.7. 权限判断

		
	# 判断文件写权限
    ret = os.access(filename, os.W_OK)
    print('文件的写权限:',ret)

	# 判断文件读权限
	ret = os.access(filename,os.R_OK)
    print('文件的读权限:',ret)		
    
	# 判断文件执行权限
	ret = os.access(filename, os.X_OK)
	print('文件的执行权限:',ret)
    
		
		

2.1.8. 判断文件/路径是否存在

		
# 判断是否为路径且存在
os.path.isdir()
# 判断是否为文件且存在
os.path.isfile()
# 判断是否存在 路径-文件
os.path.exists()
os.path.isabs()	
		
		

2.1.9. 路径拼接

os.path.join()

		
os.path.join('path1','path2')
os.path.join('path1','path2','path3')
os.path.join('path1','path2','path3','path4')
		
		

2.1.10. 目录和文件列表

2.1.10.1. 遍历当前目录

			
import os

path = "/etc"
files = []
for name in os.listdir("/etc/"):
    if os.path.isfile(os.path.join(path, name)):
        files.append(name)

print(files)	
			
			

随机抽取一个文件

			
import os
from random import choice

path = "/etc"
files = []
for name in os.listdir("/etc/"):
    if os.path.isfile(os.path.join(path, name)):
        files.append(name)

file = choice(files)
print(file)
			
			

2.1.10.2. 递归遍历目录

os.walk() 的基本用法



os.walk(top, topdown=True, onerror=None, followlinks=False) 是 os 模块中的一个函数,用于生成遍历目录树的文件名。这个函数返回一个三元组 (dirpath, dirnames, filenames)。

参数详解

top:要遍历的顶级目录的路径。
topdown (可选):如果为 True(默认值),则从顶级开始向下遍历。如果为 False,则从底部的子目录开始向上遍历。
onerror (可选):是一个函数,用于错误处理。如果指定,则应该是一个接受单个参数(异常实例)的函数。如果未指定或为 None,错误将被忽略。
followlinks (可选):如果为 True,则会遍历符号链接指向的目录。

返回值

dirpath 是一个字符串,表示正在遍历的目录的路径。
dirnames 是一个列表,包含了 dirpath 下所有子目录的名字,不包含孙子目录。
filenames 是一个列表,包含了非目录文件的名字。

			
    def walkdir(self):
        for dirpath, dirnames, filenames in os.walk('/etc'):
            print(f"dirpath={dirpath}, dirnames={dirnames}, filenames={filenames}")
            # print(filenames)			
			
			

使用 os.listdir 手工实现递归列目录

			
    def scandir(self, path):
        try:

            for name in os.listdir(path):
                current_path = os.path.join(path, name)
                access = os.access(current_path, os.R_OK)
                if access:
                    # print(access)
                    if os.path.isfile(current_path):
                        print(current_path)

                    if os.path.isdir(current_path):
                        self.scandir(current_path)
    
        except Exception as e:
            print(e)
            
    # 是否允许递归
    def scandir(self, path, recursion=False):
        try:

            for name in os.listdir(path):
                current_path = os.path.join(path, name)
                access = os.access(current_path, os.R_OK)
                if access:
                    # print(access)
                    if os.path.isfile(current_path):
                        print(current_path)

                    if recursion and os.path.isdir(current_path):
                        self.scandir(current_path)
        except Exception as e:
            print(e)            
	        
			

glob

			
    def glob(self):
    	# 当前目录
        for file in glob.glob('*.conf', root_dir='/etc'):
            print(file)			

		# 递归遍历目录
        for file in glob.glob('**/*.conf', root_dir='/etc'):
            print(file)			
			
			

2.1.11. os.scandir 扫描目录

		
import os

for entry in os.scandir(path='.'):
    print(entry.path)		
		
		
		
import os

for entry in os.scandir(path='../'):
    if entry.is_file():
        print(entry.name)
		
		

2.1.12. 删除文件或目录

删除文件

		
import os

os.remove(path) 
		
		

删除空文件夹 os.removedirs(path)

		
import os	
os.removedirs("/path/to/your")		
		
		

递归删除文件夹

		
import shutil
shutil.rmtree(path)		
		
		

2.1.13. 路径操作

2.1.13.1. 返回绝对路径

			
	file_path_1 = './test.txt'
	file_path_abs = os.path.abspath(file_path_1)		
			
			

2.1.13.2. 获取父目录

			
from pathlib import Path

path1 = Path(r"C:\folder\subfolder\file.txt")
path2 = Path(r"C:\file.txt")
path3 = Path(r"/home/neo/file.txt")
print(path1.parent)
print(path2.parent)
print(path3.parent)
print(path3.parent.parent)	
			
			

输出结果

			
C:\folder\subfolder
C:\
\home\neo
\home			
			
			
			
from pathlib import Path
p1 = Path("/Users/neo/files/neo.txt")
print(p1.parent.absolute())
print(p1.parents[2])
			
			

输出结果

			
D:\Users\neo\files
\Users		
			
			
			
import os
from pathlib import Path

path1 = Path(r"C:\folder\subfolder\file.txt")
path2 = Path(r"/home/neo/file.txt")

print(os.path.abspath(os.path.join(path1, os.pardir)))
print(os.path.abspath(os.path.join(path2, os.pardir)))

print(os.path.abspath(os.path.join(path1, '..')))
print(os.path.abspath(os.path.join(path2, '..')))

print(os.path.dirname(path1))
print(os.path.dirname(path2))

print(os.path.dirname(os.path.dirname(path1)))
			
			

输出结果

			
C:\folder\subfolder
D:\home\neo
C:\folder\subfolder
D:\home\neo
C:\folder\subfolder
\home\neo	
			
			

2.1.14. 复制文件

		
import shutil

# 定义源文件和目标文件的路径
src_path = "path/to/source/file.txt"
dst_path = "path/to/destination/file.txt"

# 复制文件
shutil.copy(src_path, dst_path)
		
		
		
from pathlib import Path

# 定义源文件和目标文件的路径
src_path = Path("path/to/source/file.txt")
dst_path = Path("path/to/destination/file.txt")

# 复制文件
src_path.copy(dst_path)


# 打开源文件和目标文件
with open(src_file, "rb") as src, open(dst_file, "wb") as dst:
    # 读取源文件内容并写入目标文件
    data = src.read()
    dst.write(data)