CSDN话题挑战赛第2期 参赛话题:学习笔记
命令行解析
手工编写 Python 命令行解析,支持 ‘-x’ 或者 ‘–x’ 类型选项处理,如果没有指定值则设置为True。
代码语言:javascript复制import sys
def error(info):
print(info)
sys.exit(0)
def parse_option(token):
if len(token) == 0 or len(token) == 1 or token[0] != '-':
error("格式错误,选项长度至少大于2并且第一个字符必须是 '-'")
if token[1] != '-':
return token[1:]
if len(token) == 2 or token[2] == '-':
error("格式错误,不支持空选项 '--' 或则三横杆选项 '---x' ")
return token[2:]
def parse_value(token):
if token is None:
return True
if len(token) == 0:
return True
if token[0] == '-':
error('格式错误')
else:
return token
if __name__ == '__main__':
count = len(sys.argv)
options = {}
# 在此使用 parse_option 和 parse_value 解析命令行
i = 1
while i < count:
token = sys.argv[i]
next_token = None
if i 1 < count:
next_token = sys.argv[i 1]
i = i 1
option = parse_option(token)
value = parse_value(next_token)
options[option] = value
i = 1
for option in options:
value = options[option]
print("{}={}".format(option, value))
使用 optparse 库配置指定命令行选项,并解析命令行
- 选项 ‘-s’ 和选项 ‘–server’ 等价
- 选项 ‘–host’ 设置默认为 0.0.0.0
- 选项 ‘–port’ 设置默认为 80
- 选项 ‘–ssl’ 如果指定,则 option.ssl=True。
# 使用 optparse 库配置指定命令行选项,并解析命令行
# 1. 选项 '-s' 和选项 '--server' 等价
# 2. 选项 '--host' 设置默认为 0.0.0.0
# 3. 选项 '--port' 设置默认为 80
# 4. 选项 '--ssl' 如果指定,则 option.ssl=True。
from ast import parse
from optparse import OptionParser
if __name__ == "__main__":
parser = OptionParser()
# 在此添加上述要求的4个命令行参数选项配置
parser.add_option(
"-s", "--server",
dest="server",
help="server",
metavar="SERVER"
)
parser.add_option(
"-h", "--host",
dest="host",
help="host",
default='0.0.0.0',
metavar="HOST"
)
parser.add_option(
'-p', "--port",
dest="port",
help="port",
default='80',
metavar="PORT"
)
parser.add_option(
"--ssl",
dest="ssl",
help="ssl",
action="store_true",
metavar="SSL"
)
(options, args) = parser.parse_args()
print(f"server={options.server}")
print(f"host={options.host}")
print(f"port={options.port}")
print(f"ssl={options.ssl}")
时间日期
计算昨天和明天的日期:
代码语言:javascript复制from datetime import datetime, timedelta
if __name__ == '__main__':
today = datetime.now()
print(today)
print(today.strftime("%d/%m/%y"))
print(today.strftime("%A %d %B %Y"))
# 在此计算昨天和明天日期
# yesterday = today timedelta(weeks=0, days=-1)
# nextday = today timedelta(weeks=0, days=1)
yesterday = today - timedelta(days=1)
nextday = today - timedelta(days=-1)
# yesterday = today timedelta(days=-1)
# nextday = today timedelta(days=1)
print(yesterday)
print(nextday)
便利的 Python 计时器,统计从 0 遍历到 100000 消耗的时间,精确到毫秒。
代码语言:javascript复制# 便利的 Python 计时器,统计从 0 遍历到 100000 消耗的时间,精确到毫秒
from datetime import datetime
from time import time, mktime
class TimeSpan:
def __init__(self) -> None:
self.start = round(time() * 1000)
# 在此计算从开始到现在的耗时,精确到毫秒
def elapse_mill_secs(self):
end = round(datetime.now().timestamp() * 1000)
return end - self.start
# def elapse_mill_secs(self):
# end = round(time() * 1000)
# return end - self.start
# def elapse_mill_secs(self):
# end = round(mktime(datetime.now().timetuple()) * 1000)
# return end - self.start
def elapse_secs(self):
return (self.elapse_mill_secs())/1000
if __name__ == '__main__':
s = TimeSpan()
for i in range(0, 100000):
pass
print('耗时: {} 毫秒'.format(s.elapse_mill_secs()))
print('耗时: {} 秒'.format(s.elapse_secs()))
从2008年1月开始到本月,遍历每一个月份的1号,并打印信息。
代码语言:javascript复制from datetime import date, timedelta
from calendar import monthrange
def next_month(d):
# 在此实现计算下一个月的代码
# 方式一
# offset = monthrange(d.year, d.month)
# first_weeky_day, days_in_month = offset
# value = d timedelta(days_in_month)
# 方式二
# days_in_month = monthrange(d.year, d.month)[1]
# value = d timedelta(days_in_month)
# 方式三
offset = monthrange(d.year, d.month)
days_in_month = offset[1]
value = d timedelta(days_in_month)
return value
def for_each_month(start, finish, action):
while start < finish:
action(start)
start = next_month(start)
if __name__ == '__main__':
for_each_month(
date(2008, 1, 1),
date.today(),
lambda d: print(d)
)
数据文件读写
Python 创建文件夹
使用 os 递归创建文件夹,已存在就覆盖
代码语言:javascript复制import os
if __name__ == '__main__':
os.makedirs(
"/tmp/test/test/test/",
exist_ok=True
)
Python 文件夹拷贝
实现文件夹拷贝,要求如下:
- 使用 shutil 拷贝 “copy.py” 文件到 “/tmp/copy.py”
- 拷贝 “copy.py” 文件到 “/tmp/copy2.py”, 保留元数据
- 递归拷贝目录 “./” 到 “/tmp/file_test/”,如果已存在就覆盖
# 实现文件夹拷贝,要求如下:
#
# 使用 shutil 拷贝 "copy.py" 文件到 "/tmp/copy.py"
# 拷贝 "copy.py" 文件到 "/tmp/copy2.py", 保留元数据
# 递归拷贝目录 "./" 到 "/tmp/file_test/",如果已存在就覆盖
import shutil
def test():
# 拷贝文件
shutil.copy(
"copy.py",
"/tmp/copy.py"
)
# 拷贝文件,保持元数据
shutil.copy2(
"copy.py",
"/tmp/copy2.py"
)
# 递归拷贝目录
shutil.copytree(
"./",
"/tmp/file_test/",
dirs_exist_ok=True
)
if __name__ == '__main__':
test()
文件遍历
稳定排序地遍历一个文件下的文件
代码语言:javascript复制# 稳定排序地遍历一个文件下的文件
import os
def ordered_list_dir(dir):
entries = os.listdir(dir)
entries.sort()
return entries
if __name__ == '__main__':
entries = ordered_list_dir('./')
for entry in entries:
print(entry)
代码语言:javascript复制# 遍历一个文件夹下的所有子文件夹,并返回所有'config.json'文件的绝对路径列表
import os
def retrieve_file_paths(dir_name):
file_paths = []
abs_dir_name = os.path.abspath(dir_name)
# 在此实现遍历代码
for base, dirs, files in os.walk(abs_dir_name):
for dir in dirs:
cfg_file = os.path.join(base, dir, 'config.json')
if os.path.exists(cfg_file):
file_paths.append(cfg_file)
return file_paths
if __name__ == '__main__':
file_paths = retrieve_file_paths('./')
print(file_paths)
文件统计
统计文件中行数,非空行数,以及空格间隔的token数
代码语言:javascript复制# 统计文件中行数,非空行数,以及空格间隔的token数
# -*- coding: UTF-8 -*-
import json
def count_file(file):
line_count = 0
non_empty_line_count = 0
token_count = 0
with open(file, 'r') as f:
while True:
# 读取每行
line = f.readline()
if not line:
break
line_count = 1
line_len = len(line)
line_token_count = 0
# 实现统计单行token数
blank = False
for char in line:
if char in [' ', 't', 'b']:
blank = True
else:
if blank:
line_token_count = 1
blank = False
token_count = line_token_count
if line_token_count > 0:
non_empty_line_count = 1
return {
'file': file,
'line_count': line_count,
'line_token_count': token_count,
'non_empty_line_count': non_empty_line_count
}
if __name__ == '__main__':
ret = count_file('count_file.py')
print('行数:', ret['line_count'])
print('非空行:', ret['non_empty_line_count'])
print('非空词数:', ret['line_token_count'])
with open('/tmp/count.json', 'w') as f:
f.write(json.dumps(ret, indent=2, ensure_ascii=False))
文件夹压缩
使用shutil对文件夹进行zip压缩,压缩过程显示进度条
代码语言:javascript复制# 使用shutil对文件夹进行zip压缩,压缩过程显示进度条
import os
import shutil
import logging
from progress.bar import IncrementalBar
logger = logging.getLogger(__name__)
def count_files_in_dir(dir):
totalFiles = 0
for base, dirs, files in os.walk(dir):
totalFiles = len(files)
return totalFiles
def zip_with_progress(dir_path, zip_file):
bar = None
total_files = count_files_in_dir(dir_path)
# 进度条显示
def progress(*args, **kwargs):
if not args[0].startswith('adding'):
return
nonlocal bar, total_files
if bar is None:
print('@开始压缩:{}'.format(zip_file))
bar = IncrementalBar('正在压缩:', max=total_files)
bar.next(1)
# 调用shutil.make_archive时,临时替换其 logger 参数,用来显示进度条
old_info = logger.info
logger.info = lambda *args, **kwargs: progress(*args, **kwargs)
shutil.make_archive(dir_path, 'zip', dir_path, logger=logger)
logger.info = old_info
if bar is not None:
bar.finish()
if __name__ == '__main__':
zip_with_progress('./', '/tmp/test_file_zip.zip')
print()