目录


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)
  • 1.
  • 2.
  • 3.
  • 4.
2. 组合

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

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

注意: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")
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
2. 随机选择多个值
from random import sample
sample([1,2,3,4],3)
sample(("a","b","c","d"),2)
sample(range(100),4)
sample("python",3)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
3. 获取随机整数
from random import randint
randint(38,74) # [38,74)
  • 1.
  • 2.
4. 获取随机浮点数
from random import random
random() # (0,1)
  • 1.
  • 2.

三、正则表达式

正则表达式的常见元字符

模式匹配
\d数字
\D非数字
\w字母数字下划线组成的单词(空白字符分割)
\W非单词
\s空白字符(" “,”\t",“\n”,“\r”)
\S非空白字符
\b单词边界(\w和\W之间)
\B非单词边界
abc字面量
(expr)分组
expr1│expr2expr1或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))
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.

四、日期的使用

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)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.

另一种方式

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.
  • 2.
  • 3.
  • 4.
  • 5.

五、文本文件的读写

1. 文本文件的读

使用到的函数:

fileobj=open(filename, mode)
  • 1.

字符串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编码的统一转换。
Python基础知识-4_随机数
VSCode文本文件编码格式转换的其他方式:
Ctrl + Shift + p,然后在命令窗口中输入Reopen with Encoding
或者点击下图箭头所示位置“选择编码”
Python基础知识-4_文本文件_02
Python基础知识-4_随机数_03
通过编码重新打开
Python基础知识-4_文本文件_04
Python基础知识-4_正则_05
通过尝试找到无乱码的正确编码,或者最初使用VSCode打开文件时状态栏会显示检测到的编码格式。
Python基础知识-4_文本文件_06
Python基础知识-4_随机数_07
然后使用通过编码保存。

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

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

1.2. 使用迭代器逐行读取文本文件
with open("file.txt", "r") as file:
    for line in file:
        # 处理读取的行数据
        print(line)
  • 1.
  • 2.
  • 3.
  • 4.
1.3. 将文件内容全部读入列表,然后逐行处理。
with open("file.txt", "r") as file:
    lines = file.readlines()
    for line in lines:
        # 处理读取的行数据
        print(line)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
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)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
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())
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

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

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