burpow
python语法(下)

python语法(下)

Python3 推导式

列表推导式

列表推导式格式为:

1
2
3
4
5
6
7
[表达式 for 变量 in 列表] 
[out_exp_res for out_exp in input_list]

或者

[表达式 for 变量 in 列表 if 条件]
[out_exp_res for out_exp in input_list if condition]

例题:

1
2
3
4
>>> names = ['Bob','Tom','alice','Jerry','Wendy','Smith']
>>> new_names = [name.upper()for name in names if len(name)>3]
>>> print(new_names)
['ALICE', 'JERRY', 'WENDY', 'SMITH']

实现了:==遍历旧列表,判断,操作,生成新列表==

字典推导式

字典推导基本格式:

1
2
3
4
5
{ key_expr: value_expr for value in collection }



{ key_expr: value_expr for value in collection if condition }

例题:

1
2
3
>>> dic = {x: x**2 for x in (2, 4, 6)}  # 其中,x: x**2位键值对示例
>>> dic
{2: 4, 4: 16, 6: 36}

集合推导式

同理(与字典推导式),最前面为示例(expression)

元组推导式(生成器表达式)

只不过,元组推导式返回的结果是一个生成器对象

1
2
3
4
5
6
>>> a = (x for x in range(1,10))
>>> a
<generator object <genexpr> at 0x7faf6ee20a50> # 返回的是生成器对象

>>> tuple(a) # 使用 tuple() 函数,可以直接将生成器对象转换成元组
(1, 2, 3, 4, 5, 6, 7, 8, 9)

Python3 迭代器与生成器

from【Python】从迭代器到生成器:小内存也能处理大数据_哔哩哔哩_bilibili
from『教程』几分钟听懂迭代器_哔哩哔哩_bilibili

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。Python3 迭代器与生成器 | 菜鸟教程

引入:for循环的原理

迭代器判断(迭代器协议):一个对象,只要它有__iter__方法,有__next__方法,就是一个迭代器。
验证某个对象是否有某种方法:hasattr(obj,'method')

iter(可迭代对象)/__iter__(迭代器)–>返回一个迭代器
next(迭代器)/__next__(迭代器)–>依次返回下一个值

实战:自定义一个迭代器,包含__init__,__iter__,__next__

惰性加载省内存:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import tracemalloc

tracemalloc.start()
class LineIterator:
def init_(self, filepath):
self.file = open(filepath,
def iter_(self):
return self
def next_(self)
line = self.file.readline()
if line:
return line
else:
self.file.close()
raise StopIteration

line_iter = LineIterator(filepath)
for line in line_iter:
process_line(line) # process_line是一个自定义函数用来处理每一行的结果罢了

current, peak = tracemalloc.get_traced_memory()
print(f"Current memory usage:{current/1024**2} MB)
print(f"Peak memory usage:{peak/1024**2} MB)
tracemalloc.stop()

处理日志文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class LineIterator:
def __init__(self, filepath):
self.file = open(filepath, 'r')

def __iter__(self):
return self

def __next__(self):
line = self.file.readline()
while line:
if line.split('|')[2].strip() == 'Create':
return line
line = self.file.readline()
self.file.close()
raise StopIteration

line_iter = LineIterator(filepath)
for line in line_iter:
print(line)

生成器则可以省略两个方法__iter__,__next__进行简化
(待完成)

特性:处理大型文件,实现惰性加载

Python with 关键字

with 语句的基本语法

1
2
with open("","") [as variable]:  
    # 代码块
  • expression 返回一个支持上下文管理协议的对象
  • as variable 是可选的,用于将表达式结果赋值给变量
  • 代码块执行完毕后,自动调用清理方法

文件操作示例

最常见的 with 语句应用是文件操作:

1
2
3
4
with open('example.txt', 'r') as file:  
    content = file.read()
    print(content)
# 文件已自动关闭

这段代码等价于前面的 try-finally 实现,但更加简洁明了。

with 语句背后是 Python 的上下文管理协议,该协议要求对象实现两个方法:

  1. __enter__():进入上下文时调用,返回值赋给 as 后的变量
  2. __exit__():退出上下文时调用,处理清理工作

Python3 函数

基本语法:

1
2
3
def 函数名(参数列表):
函数体
[return()]

可更改(mutable)与不可更改(immutable)对象

对象有不同类型的区分,变量是没有类型的:

1
2
a=[1,2,3]
a="Runoob"

以上代码中,[1,2,3] 是 List 类型,”Runoob” 是 String 类型,而变量 a 是没有类型,它仅仅是一个对象的引用(一个指针),可以是指向 List 类型对象,也可以是指向 String 类型对象。

在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。

python 函数的参数传递:

  • 不可变类型:类似 C++ 的值传递,如整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在 fun(a) 内部修改 a 的值,则是新生成一个 a 的对象。
  • 可变类型:类似 C++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la 也会受影响

python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。

参数

以下是调用函数时可使用的正式参数类型:

参数类型 说明
必需参数 没有默认参数时,不传参会报错
关键字参数 用参数名匹配参数值
默认参数 不传参会使用默认参数
不定长参数 可接收任意数量的参数(见下···)

不定长参数

希望一个函数能处理比当初声明时更多的参数:

1
2
3
def functionname([formal_args,] *var_args_tuple ):
"函数体"
return [expression]
  1. 加了星号 * 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数,举例:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #!/usr/bin/python3

    # 可写函数说明
    def printinfo( arg1, *vartuple ):
    "打印任何传入的参数"
    print ("输出: ")
    print (arg1)
    for var in vartuple:
    print (var)
    return

    # 调用printinfo 函数
    printinfo( 10 )
    printinfo( 70, 60, 50 )
  2. 加了两个星号 ** 的参数会以字典的形式导入。
    1
    2
    3
    def functionname([formal_args,] **var_args_dict ):
    "函数体"
    return [expression]
  3. 如果单独出现星号 *,则星号 * 后的参数必须用关键字传入,*不计入参数数。
    1
    2
    3
    4
    5
    6
    7
    >>> def f(a,b,*,c):
    ... return a+b+c
    ...
    >>> f(1,2,3) # 报错
    (error省略)
    >>> f(1,2,c=3) # 正常
    6

强制位置参数(Python3.8+)

在以下的例子中,形参 a 和 b 必须使用指定位置参数,c 或 d 可以是位置形参或关键字形参,而 e 和 f 要求为关键字形参:

1
2
def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)

以下使用方法是正确的:

1
f(10, 20, 30, d=40, e=50, f=60)

Python3 匿名函数

语法:lambda (参数列表):(操作)

例如:

1
2
3
def f(a):
return (a+10)
print(f(5))

等价于

1
2
x = lambda a : a + 10
print(x(5)) # 只保留关键部分:参数+操作

lambda 函数通常与内置函数如 map()、filter() 和 reduce() 一起使用。

这些内置函数都接受两个参数:函数和可迭代对象
map()返回列表(py2)或迭代器(py3)
filter()返回一个迭代器对象,实现筛选
reduce()返回函数计算结果,实现累加或累积【具体实现流程:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果】

Python 装饰器

无参数函数的装饰器

1
2
3
4
5
6
7
8
9
10
11
12
def my_decorator(func):  
    def wrapper():
        print("在原函数之前执行")
        func()
        print("在原函数之后执行")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()

输出:

1
2
3
在原函数之前执行
Hello!
在原函数之后执行

带参数函数的装饰器

1
2
3
4
5
6
7
8
9
10
11
12
def my_decorator(func):  
    def wrapper(*args, **kwargs):
        print("在原函数之前执行")
        func(*args, **kwargs)
        print("在原函数之后执行")
    return wrapper

@my_decorator
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")

输出:

1
2
3
在原函数之前执行
Hello, Alice!
在原函数之后执行
语法 处理参数类型 内部存储类型
*args 位置参数 元组
**kwargs 关键字参数(键值对) 字典
装饰器本身也可以接受参数,此时需要额外定义一个外层函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
def repeat(num_times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(num_times):
func(*args, **kwargs)
return wrapper
return decorator

@repeat(3)
def say_hello():
print("Hello!")

say_hello()

输出:

1
2
3
Hello!
Hello!
Hello!

Python3 数据结构

列表

方法 描述
list.append(x) 把一个元素添加到列表的结尾
list.extend(L) 通过添加指定列表的所有元素来扩充列表
list.insert(i, x) 在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引
list.remove(x) 删除列表中值为 x 的第一个元素(==指定值移除==)
list.pop([i]) 从列表的==指定位置移除==元素,并将其返回。如果没有指定索引,a.pop()返回最后一个元素。元素随即从列表中被移除。
list.clear() 移除列表中的所有项
list.index(x) 返回列表中==第一个==值为 x 的元素的==索引==
list.count(x) 返回 x 在列表中==出现的次数==
list.sort() 对列表中的元素进行==排序==
list.reverse() 倒排列表中的元素
list.copy() 返回列表的浅复制,等于a[:]。(无参数)
可以将列表当做栈(LIFO)使用,也可以将列表当作队列(FIFO)使用(一般使用 collections.deque 实现队列)

字典

遍历字典技巧

在字典中遍历时,关键字和对应的值可以使用 items() 方法同时解读出来:

1
2
3
4
5
6
>>> knights = {'gallahad''the pure''robin''the brave'}  
>>> for k, v in knights.items():
...     print(k, v)
...
gallahad the pure
robin the brave

在序列中遍历时,索引位置和对应值可以使用 enumerate() 函数同时得到:

1
2
3
4
5
6
>>> for i, v in enumerate(['tic''tac''toe']):  
...     print(i, v)
...
0 tic
1 tac
2 toe

同时遍历两个或更多的序列,可以使用 zip() 组合:

1
2
3
4
5
6
7
8
>>> questions = ['name''quest''favorite color']  
>>> answers = ['lancelot''the holy grail''blue']
>>> for q, a in zip(questions, answers):
...     print('What is your {0}?  It is {1}.'.format(q, a))
...
What is your name?  It is lancelot.
What is your quest?  It is the holy grail.
What is your favorite color?  It is blue.

补充

Python list 常用操作 | 菜鸟教程一共有11个操作,都要学会

Python3 模块

查看官方文档Python 标准库 — Python 3.14.2 文档
也可以去查看他的源代码:lib文件夹内
也可以引入python第三方库PyPI · The Python Package Index,使用pip命令安装

引入模块,如:

1
2
import statistics
print(sttistics.median([69,124,-47,89,10]))

from statistics import median(或*来匹配全部函数)

[!NOTE]

  • 内置函数:直接用「函数名(参数)」调用,如 len("test") ;
  • 模块函数:用「模块名.函数名(参数)」调用,需先导入模块,如 math.sin(0)

Python __name____main__

__name__ 是一个内置变量,表示当前模块的名称。

假设我们有一个名为 example.py 的模块:

1
2
3
4
5
6
7
8
def greet():  
    print("来自 example 模块的问候!")

if __name__ == "__main__":
    print("该脚本正在直接运行。")
    greet()
else:
    print("该脚本作为模块被导入。")

如果你直接运行 example.py,输出将是:

1
2
该脚本正在直接运行。
来自 example 模块的问候!

在这种情况下,__name__ 的值是 “__main__“,所以 if __name__ == "__main__": 块中的代码会被执行。

如果你在另一个脚本中导入 example.py,例如:

1
2
3
4
5
# another_script.py  

import example

example.greet()

输出将是:

1
2
该脚本作为模块被导入。
来自 example 模块的问候!

在这种情况下,__name__ 的值是 “example”(模块名),所以 if __name__ == "__main__": 块中的代码不会被执行。

Python 爬虫(bs4模块)

爬虫的基本流程通常包括发送 HTTP 请求获取网页内容、解析网页并提取数据,然后存储数据。

解决中文乱码问题:
如果你知道网页的编码,可以直接设置 response.encoding:
response.encoding = 'utf-8' # 或者 'gbk',根据实际情况选择

获取标签内嵌的文本:get_text()

1
2
# 获取第一个 <p> 标签中的文本内容  
paragraph_text = soup.find('p').get_text()

查找子标签和父标签:parent 和 children 属性

1
2
3
4
5
# 获取当前标签的父标签
parent_tag = first_link.parent

# 获取当前标签的所有子标签
children = first_link.children

查找具有特定属性的特定标签:atters参数(字典)

1
all_titles = soup.findAll("span", attrs={"class": "title"})

如果是class属性或id属性,可以用class_=""id=""

获取标签下的另一个属性:

1
2
3
4
5
6
# 查找具有 id="su" 的 <input> 标签
unique_input = soup.find('input', id='su')

input_value = unique_input['value'] # 获取该 input 标签下的 value 属性内容

print(input_value) # 输出:百度一下

[[CSS 选择器]]

1
2
3
4
5
# 使用 CSS 选择器查找所有 class 属性为 'example' 的 <div> 标签
example_divs = soup.select('div.example')

# 查找所有 <a> 标签中的 href 属性
links = soup.select('a[href="https:www.example.com"]')

修改网页内容

1
2
3
# 修改第一个 <p> 标签的文本内容  
first_paragraph = soup.find('p')
first_paragraph.string = 'Updated content'

转换为字符串

你可以将解析的 [^1]BeautifulSoup 对象转换回 HTML 字符串:

1
2
# 转换为字符串
html_str = str(soup)

Python requests 模块

每次调用 requests 请求之后,会返回一个 response 对象,该对象包含了具体的响应信息,如状态码、响应头、响应内容等:

1
2
3
4
print(response.status_code)  # 获取响应状态码
print(response.headers) # 获取响应头
print(response.content) # 获取响应体,byte类型,再去指定编码
print(response.text) # 查看响应内容,response.text 返回的是Unicode格式的数据

如:

1
2
3
4
5
6
7
8
9
10
11
12
# 导入 requests 包
import requests

# 发送请求
x = requests.get('https://www.runoob.com/')

# 返回 http 的状态码
print(x.status_code)

# 返回请求头
for key,value in x.headers.items():
print(key,':',value)
方法 描述
get(urlparams, args) 发送 GET 请求到指定 url
post(urldata, json, args) 发送 POST 请求到指定 url
request(methodurlargs) 向指定的 url 发送指定的请求方法
request方法,如:
1
2
3
4
5
6
7
8
# 导入 requests 包
import requests

# 发送请求
x = requests.request('get', 'https://www.runoob.com/')

# 返回网页内容
print(x.status_code)

Python3 输入和输出

输入

举例:

1
user_height=float(input("请输入你的身高"))

输出格式美化

str.rjust() 的基本使用
它可以将字符串靠右, 并在左边填充空格。

1
2
3
4
5
6
7
8
9
10
>>> for x in range(16):  
...     print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')
...     # 注意前一行 'end' 的使用
...     print(repr(x*x*x).rjust(4))
...
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125

还有类似的方法, 如 ljust() 和 center()。

str.format() 的基本使用
%%当然,还有%法和f-string法%%
括号及其里面的字符 (称作格式化字段) 将会被 format() 中的参数替换。
在括号中的数字用于指向传入对象在 format() 中的位置

1
2
>>> print('站点列表 {0}, {1}, 和 {other}。'.format('Google', 'Runoob', other='Taobao'))
站点列表 Google, Runoob, 和 Taobao。

可选项:使用示例:{0:.3f}

Python文件操作

文件路径

linux/
windows

读写文件

%%003%%

如:

1
2
3
f=open("{路径名}","r/w")
print(f.read())
f.close()

或者用with方法:

1
2
with open(" ./data.txt") as f: 
print(f. read())

完整示例:%%模式有^2rwa%%

1
2
3
4
5
with open("./poem.txt","w+") as f:  # w+支持读,写,创建新文件
f.write("wa\nwa\nwa\n")
f.write("pa\npa") # 也可以再写出一行,以"a"模式
f.seek(0) # 将文件指针移回开头
print(f.read())

Python3 OS 文件/目录方法

通过 os 模块,你可以执行文件操作、目录操作、环境变量管理、进程管理等任务。

  1. 获取当前工作目录
  2. 改变当前工作目录
  3. 列出目录内容
  4. 创建目录
  5. 删除目录
  6. 删除文件
  7. 重命名文件或目录
  8. 获取环境变量
  9. 执行系统命令os.system(command)

Python3 错误和异常

try...except...else...finally...

Python 面向对象

  • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
  • 实例化: 创建一个类的实例,类的具体对象。
  • 对象: 通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

简述:

是模板,对象是实例,方法是放在类里面的函数
都有属性,且可以区分来自不同对象的属性,属性可以被方法直接获取(不用作为参数)
特点:封装,继承,多态

基本语法

%%001%%
定义属性,定义方法,创建对象,调用属性,调用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Student:
def __init__(self,name,id,yw,sx,yy):
self.name=name
self.id=id
self.yw=yw
self.sx=sx
self.yy=yy

def caculate_all(self):
print(f"总成绩为:{self.yw+self.sx+self.yy}")

zhangsan=Student("张三",202510,110,120,130)
print(zhangsan.id)
zhangsan.caculate_all()

继承(父子类)

%%002%%

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
class yuangong:
def __init__(self,name,id):
self.name=name
self.id=id
self.work_city="zhongshan"

def print_info(self):
print(f"员工姓名:{self.name},id:{self.id},city:{self.work_city}")

class quanzhi(yuangong):
def __init__(self, name, id, yx):
super().__init__(name, id) # 继承父类的属性,少写两行self.name=name,self.id=id | super()表示父类
self.yx=yx

def salary_count(self):
return self.yx

class jianzhi(yuangong):
def __init__(self, name, id,rx,days):
super().__init__(name, id)
self.rx=rx
self.days=days

def salary_count(self):
return self.rx*self.days

zhangsan=quanzhi("张三",202510,6000) # 同名时优先用子类的属性/方法
lisi=jianzhi("李四",202511,180,15)
zhangsan.print_info() # 继承父类的方法 | 点表示法调用格式:对象.属性/方法
lisi.print_info()
print(zhangsan.salary_count())
print(lisi.salary_count())
print(zhangsan.id)

python测试模块:unittest

%%004%%

再在终端运行python -m unittest

测试代码:(”test_”开头的文件名)

1
2
3
4
5
6
7
8
9
10
11
import unittest:
from {同目录下被测试文件名} import {被测试文件类名}

class {自定义类名} (unittest.TestCase):
def setUp(self):
self.{自定义属性}={被测试文件类名}({被传入的数据}) # 该方法设置原文件的默认属性

def {"test_"开头的方法名} (self):
self.{assertEqual等}(参数1,参数2) # my_adder(3,5),8

def...

Python 虚拟环境的创建(venv)

完整示例

假设开发一个 Django 项目:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 创建环境并激活  
python3 -m venv .venv
source .venv/bin/activate

# 安装Django
(.venv) pip install django==3.2.12

# 创建Django项目
(.venv) django-admin startproject my_site

# 运行测试
(.venv) cd my_site
(.venv) python manage.py runserver

# 完成后退出环境
(.venv) deactivate

目录结构

创建.venv后的目录结构

1
2
3
4
5
6
7
8
9
10
.venv/
├── bin/ # 在 Unix/Linux 系统上
│ ├── activate # 激活脚本
│ ├── python # 环境 Python 解释器
│ └── pip # 环境的 pip
├── Scripts/ # 在 Windows 系统上
│ ├── activate # 激活脚本
│ ├── python.exe # 环境 Python 解释器
│ └── pip.exe # 环境的 pip
└── Lib/ # 安装的第三方库

使用虚拟环境

%%记得激活与退出%%

安装包

在激活的环境中,使用 pip 安装的包只会影响当前环境:

1
pip install package_name

例如:

1
2
3
4
5
# 安装单个包(如Django)
(.venv) pip install django==3.2.12

# 安装多个包
(.venv) pip install requests pandas

查看已安装的包

1
2
3
4
5
(.venv) pip list
Package Version
---------- -------
Django 3.2.12
pip 21.2.4

导出依赖

1
(.venv) pip freeze > requirements.txt

requirements.txt 文件内容示例:

1
2
3
Django==3.2.12
requests==2.26.0
pandas==1.3.3

从文件安装依赖

1
(.venv) pip install -r requirements.txt

Python 类型注解(Type Hints)

%%也可以使用typing 模块%%

基础语法

变量注解

从 Python 3.6 开始,你可以直接为变量添加类型注解:

1
2
3
4
5
6
7
8
9
10
11
# 没有类型注解的代码  
name = "Alice"
age = 30
is_student = False
scores = [958891]

# 有类型注解的代码
name: str = "Alice"       # 注解为字符串 (str)
age: int = 30             # 注解为整数 (int)
is_student: bool = False  # 注解为布尔值 (bool)
scores: list = [958891# 注解为列表 (list)

说明: name: str 读作”变量 name 的类型是 str”。

函数注解

在函数参数后加 : 类型

1
2
3
4
5
6
7
8
9
# 没有类型注解的函数  
def greet(first_name, last_name):
    full_name = first_name + " " + last_name
    return "Hello, " + full_name

# 有类型注解的函数
def greet(first_name: str, last_name: str) -> str:
    full_name = first_name + " " + last_name
    return "Hello, " + full_name

解读这个函数

  • first_name: str:参数 first_name 应该是字符串。
  • last_name: str:参数 last_name 应该是字符串。
  • -> str:这个函数执行后会返回一个字符串。

现在,任何人调用这个函数时,都能清晰地知道需要传递什么,以及会得到什么。

函数注解是类型注解最常见的应用场景:

1
2
3
4
5
6
7
def add_numbers(a: int, b: int) -> int:  
    """将两个整数相加并返回结果"""
    return a + b

# 调用函数
result = add_numbers(53)  # 正确:两个整数
# result = add_numbers("5", "3")  # 可能有问题:虽然能运行,但类型检查器会警告

参数默认值

你可以同时使用类型注解和默认值:

1
2
3
4
5
6
def say_hello(name: str, times: int = 1) -> str:  
    """向某人问好指定次数"""
    return " ".join([f"Hello, {name}!"] * times)

print(say_hello("Bob"))      # 输出:Hello, Bob!
print(say_hello("Alice"3)) # 输出:Hello, Alice! Hello, Alice! Hello, Alice!

Python3 标准库概览

菜鸟Python3 标准库概览 | 菜鸟教程
官方Python 标准库 — Python 3.14.2 文档
第三方库PyPI · The Python Package Index

[^1]: 使用 BeautifulSoup 解析 HTML 后会生成 BeautifulSoup 对象,该对象以嵌套树形结构表示整个 HTML 文档,便于后续的导航、搜索和数据提取

|---|---|---|---|---|---|---|
|读|+|+||+||+|
|写||+|+|+|+|+|
|创建|||+|+|+|+|
|覆盖|||+|+|||
|指针在开始|+|+|+|+|||
|指针在结尾|||||+|+|
本文作者:burpow
本文链接:https://youthfulnesszxx.github.io/2026/03/26/python语法(下)/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可