(目录)


PyPi也称为Cheese Shop

一、使用itertools得到排列和组合

在Python的itertools模块中,有两个函数用于处理排列和组合:permutations() 和 combinations()。

1. 全排列

permutations(iterable, r=None):创建所有长度为r的可能排列。如果未指定r,则默认为len(iterable)。

import itertools
items = ['a', 'b', 'c']
for p in itertools.permutations(items):
    print(p)

2. 组合

combinations(iterable, r):创建所有长度为r的可能组合(从iterable中选择r个不同的元素)。

import itertools
items = ['a', 'b', 'c']
for c in itertools.combinations(items, 2):
    print(c)

注意:itertools.permutations和itertools.combinations返回的是元组的迭代器,如果你需要列表,可以使用list()函数进行转换。

二、产生随机数

1. 随机选择一个值

random.choice(),该函数从指定的序列(列表,元组,字典,字符串)参数中返回一个值:

from random import choice
choice([1,2,3,4])
choice(("a","b","c","d"))
choice(range(100))
choice("python")

2. 随机选择多个值

from random import sample
sample([1,2,3,4],3)
sample(("a","b","c","d"),2)
sample(range(100),4)
sample("python",3)

3. 获取随机整数

from random import randint
randint(38,74) # [38,74)

4. 获取随机浮点数

from random import random
random() # (0,1)

三、正则表达式

正则表达式的常见元字符

模式 匹配
\d 数字
\D 非数字
\w 字母数字下划线组成的单词(空白字符分割)
\W 非单词
\s 空白字符(" ","\t","\n","\r")
\S 非空白字符
\b 单词边界(\w和\W之间)
\B 非单词边界
abc 字面量
(expr) 分组
expr1│expr2 expr1或expr2
· 除\n之外的任意字符
^和$ 源字符串的开始和结束
re? 0或1个re
re* 0或多个re,尽可能多
re*? 0或多个re,尽可能少
re+ 1或多个re,尽可能多
re+? 1或多个re,尽可能少
re{m} m个连续的re
re{m,n} m至n个连续re,尽可能多
re{m,n}? m至n个连续re,尽可能少
[abc] a或b或c
[^abc] 非a或b或c
prev(?=next) 如果后继是next,则匹配prev
prev(?!next) 如果后继不是next,则匹配prev
(?<=prev)next 如果前驱是prev,则匹配next
(?<!prev)next 如果前驱不是prev,则匹配next
import re


class FindMode:
    def __init__(self, mode, src_str):
        self.pattern = re.compile(mode)
        self.src_str = src_str

    def find_str(self, gp_no=0):
        """
        捕获组编号gp_no:
        0: 匹配整个模式
        1,2,3,...: 对应正则中()表达的第1个, 第2个, 第3个...捕获组
        """
        if m := self.pattern.search(self.src_str):
            # search 只匹配第一次找到的
            return m.group(gp_no) # group()等同于group(0)
            # groups()将以元组形式返回所有捕获组
        else:
            return ""

    def find_any(self):
        # findall 查找所有能匹配到的
        # 返回列表list
        return self.pattern.findall(self.src_str)

    def replace_str(self, subs_str):
        # 返回一个字符串
        return self.pattern.sub(subs_str, self.src_str)


if __name__ == "__main__":
    # r"xxxxx" 表示原字符串,可避免python正常的字符串转义和正则转义之间的冲突
    result = FindMode(r"(\d+)/(\d+)/(\d+)", "interface GigabitEthernet9/0/3")
    print(result.find_str())
    print(result.find_any())
    print(f"{result.find_str(1)},{result.find_str(2)},{result.find_str(3)}")
    print(result.replace_str("?/?/?"))

    str = "interface GigabitEthernet9/0/4"
    if (p := str.find("net")) != -1:
        substr = str[p + 3 :]  # 可以通过切片来求子串
        print(substr.split("/"))
        print(re.split("\d", substr))

四、日期的使用

from datetime import date, timedelta, time, datetime

# 表达日期
d = date(2022, 5, 10)
print(d.year)
print(d.month)
print(d.day)
d.isoformat()  # 得到日期字符串

# 得到当前的日期
print(date.today())

# 距当前日期三天后的日期
cu = date.today()
one_day = timedelta(days=1)
print(cu + 3 * one_day)

# 表达时间
t = time(18, 1, 2, 302)
print(t.hour, t.minute, t.second, t.microsecond)

# 获得当前日期和时间
now = datetime.now()
print(now)
print(now.year, now.month, now.day, now.hour, now.minute, now.second)

# 日期到字符串
now.strftime("%Y-%m-%d %H:%M:%S")

# 日期的构造
someday = datetime(2018, 3, 10, 21, 10, 2)
print(someday)

另一种方式

import time

# 字符串到日期
t = time.strptime("2022-03-10 20:08:11", "%Y-%m-%d %H:%M:%S")
print(t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec)

五、文本文件的读写

1. 文本文件的读

使用到的函数:

fileobj=open(filename, mode)

字符串filename指定了文件名,字符串mode的取值指定了文件类型和操作。 mode第一个字符指定了操作:

  • r 表示读取。
  • w 表示写入。如果文件不存在,则创建文件;如果文件存在,就覆盖同名文件。
  • x 表示仅在指定文件不存在时写入。可以避免文件被覆盖(会抛出FileExistsError异常)。
  • a 表示如果文件存在,则在文件末尾追加写入。 mode第二个字符指定了文件类型
  • t(或省略) 表示文本文件
  • b 表示二进制文件。

注意:mode字符串只能有2个字符组成(或者1个字符),一个指代操作,一个指代文件类型(t可省)。 文本文件还要注意统一编码。建议统一使用utf-8编码。在VSCode中可以使用GBK to UTF8 for vscode插件来完成Windows下GBK编码向UTF8编码的统一转换。 image.png VSCode文本文件编码格式转换的其他方式: Ctrl + Shift + p,然后在命令窗口中输入Reopen with Encoding 或者点击下图箭头所示位置“选择编码” image.png image.png 通过编码重新打开 image.png image.png 通过尝试找到无乱码的正确编码,或者最初使用VSCode打开文件时状态栏会显示检测到的编码格式。 image.png image.png 然后使用通过编码保存。

1.1. 使用内置函数readline()逐行读取文本文件
with open("file.txt", "r") as file:
    line = file.readline()
    while line != "":
        # 处理读取的行数据
        print(line)
        line = file.readline()

文本文件中间读到的空行包含一个字节的“\n”——不是“”;而文件结尾处读到的空行才是“”。

1.2. 使用迭代器逐行读取文本文件
with open("file.txt", "r") as file:
    for line in file:
        # 处理读取的行数据
        print(line)
1.3. 将文件内容全部读入列表,然后逐行处理。
with open("file.txt", "r") as file:
    lines = file.readlines()
    for line in lines:
        # 处理读取的行数据
        print(line)
1.4. 封装成一个文本文件处理类
########## RegularExp.py
import re


class FindMode:
    def __init__(self, mode, src_str=""):
        self.pattern = re.compile(mode)
        self.src_str = src_str

    def find_str(self, gp_no=0):
        """
        捕获组编号gp_no:
        0: 匹配整个模式
        1,2,3,...: 对应正则中()表达的第1个, 第2个, 第3个...捕获组
        """
        if m := self.pattern.search(self.src_str):
            # search 只匹配第一次找到的
            return m.group(gp_no)
        else:
            return ""

    def find_any(self):
        # findall 查找所有能匹配到的
        # 返回列表list
        return self.pattern.findall(self.src_str)

    def replace_str(self, subs_str):
        return self.pattern.sub(subs_str, self.src_str)

    def set_src_str(self, src_str):
        self.src_str = src_str

########## TxtFileRW.py
from RegularExp import FindMode


class TxtReader:
    def __init__(self, filename):
        try:
            self.txt_file = open(filename, "rt")
        except FileNotFoundError:
            print("文件未找到")
        except IsADirectoryError:
            print("是目录不是文件")
        except PermissionError:
            print("没有权限读取文件")
        except Exception as e:
            print(f"发生未知错误:{e}")

    def get_spec_lines(self, spec):
        lines = []
        fm = FindMode(spec)
        for line in self.txt_file:
            fm.set_src_str(line)
            if (str := fm.find_str()) != "":
                lines.append(str)
        return lines

    """
    避免在析构函数中进行复杂的操作。
    由于析构函数的执行时机不确定,因此不应该依赖析构函数来管理重要的资源,而应该使用上下文管理器(如with语句)。
    """

    def __del__(self):
        self.txt_file.close()

########## demo.py
from TxtFileRW import TxtReader


if __name__ == "__main__":
    txt_file = TxtReader("test.log")
    for line in txt_file.get_spec_lines(r"\w+\s+\w+\d+/\d+/\d+\.\d+"):
        print(line)

2. 文本文件的写

# 打开文件以进行写入,如果文件不存在则创建
with open('example.txt', 'w') as file:
    # 写入一行文本
    file.write('这是一行文本。\n')
    # 写入多行文本
    file.writelines(['第二行文本。\n', '第三行文本。\n'])
 
# 检查文件内容
with open('example.txt', 'r') as file:
    print(file.read())

默认情况下,print()会自动在每个参数后边添加空格,在结尾添加换行符“\n”,而上边的write()方法不会。如果希望print()和write()一样,可以如下传递参数。

fout = open("text.txt", "wt")
print("ok" * 3, file=fout, sep="", end="")
fout.close()