diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..fc30e581 --- /dev/null +++ b/.gitignore @@ -0,0 +1,146 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ +/venv/ +/venv1/ +.idea +node_modules/ +backend/combined_storage/ +backend/uploads/ +backend/reports/ +.monkeycode/ \ No newline at end of file diff --git a/03/list_tuple.py b/03/list_tuple.py new file mode 100644 index 00000000..40617f63 --- /dev/null +++ b/03/list_tuple.py @@ -0,0 +1,87 @@ +# -*- coding:utf-8 -*- +# 基础篇 03 列表list和元组tuple + +# import numpy as np +import dis + +if __name__ == "__main__": + l = [1, 2, "hello", "world"] + tup = ("jason", 22) + print(l) + print(tup) + + # 列表元素可变,元组元素不可变 + l = [1, 2, 3, 4] + l[3] = 40 + print(l) + tup = (1, 2, 3, 4) + # tup[3] = 40 + print(tup) + + # 列表和元组都支持负数索引,-1 表示最后一个元素,-2 表示倒数第二个元素 + print(l[-1]) + print(tup[-2]) + + # 增加元素 + # 创建新的元组 new_tup,并依次填充原元组的值,逗号表示这是单元素元组 + new_tup = tup + (5,) + print(new_tup) + # 添加元素 5 到原列表的末尾 + l.append(5) + print(l) + + # 片切操作,包含元素规则是左闭右开 + l = [1, 2, 3, 4] + # 返回列表中索引从 1 到 2 的子列表 + print(l[1:3]) + tup = (1, 2, 3, 4) + print(tup[1:3]) + + # 嵌套,列表和元组可以互相嵌套 + l = [[1, 2, 3], [4, 5], (6, 7)] + tup = ((1, 2, 3), (4, 5, 6), [7, 8]) + print(l) + print(tup) + + # 相互转换 + print(list((1, 2, 3))) + print(tuple([1, 2, 3])) + + # 内置函数 + l = [3, 2, 3, 7, 8, 1] + print(l.count(3)) + print(l.index(7)) + # 元组没有reverse和sort内置函数,因为元组元素不可变 + l.reverse() + print(l) + l.sort() + print(l) + + tup = (3, 2, 3, 7, 8, 1) + print(tup.count(3)) + print(tup.index(7)) + print(list(reversed(tup))) + print(sorted(tup)) + + # 列表和元组的存储差异 + l = [1, 2, 3] + tup = (1, 2, 3) + print(l.__sizeof__()) # 104 + print(tup.__sizeof__()) # 48 + + l = [] + print(l.__sizeof__()) # 40 + l.append(1) + print(l.__sizeof__()) # 72 + l.append(2) + print(l.__sizeof__()) # 72 + l.append(3) + print(l.__sizeof__()) # 72 + l.append(4) + print(l.__sizeof__()) # 72 + l.append(5) + print(l.__sizeof__()) # 104 + + # 查看字节码 + dis.dis("empty_list = list()") + dis.dis("empty_list = []") \ No newline at end of file diff --git a/03/listtuple.py b/03/listtuple.py deleted file mode 100644 index 8cd34d32..00000000 --- a/03/listtuple.py +++ /dev/null @@ -1,72 +0,0 @@ -# -*- coding:utf-8 -*- -# 基础篇 03 列表和元组 - -import numpy as np - -if __name__ == "__main__": - l = [1, 2, "hello", "world"] - tup = ("jason", 22) - print(l) - print(tup) - - l = [1, 2, 3, 4] - l[3] = 40 - print(l) - tup = (1, 2, 3, 4) - # tup[3] = 40 - print(tup) - # 增加元素 - new_tup = tup + (5,) - print(new_tup) - l.append(5) - print(l) - - # 片切操作 - l = [1, 2, 3, 4] - print(l[1:3]) - tup = (1, 2, 3, 4) - print(tup[1:3]) - - # 嵌套 - l = [[1,2,3], [4,5]] - tup = ((1,2,3), (4,5,6)) - print(l) - print(tup) - - # 相互转换 - print(list((1,2,3))) - print(tuple([1,2,3])) - - # 内置函数 - l = [3,2,3,7,8,1] - print(l.count(3)) - print(l.index(7)) - l.reverse() - print(l) - l.sort() - print(l) - - tup = (3,2,3,7,8,1) - print(tup.count(3)) - print(tup.index(7)) - print(list(reversed(tup))) - print(sorted(tup)) - - # 列表和元组的存储差异 - l = [1,2,3] - tup = (1,2,3) - print(l.__sizeof__()) #32 - print(tup.__sizeof__()) #24 - - l = [] - print(l.__sizeof__()) #20 - l.append(1) - print(l.__sizeof__()) #36 - l.append(2) - print(l.__sizeof__()) #36 - l.append(3) - print(l.__sizeof__()) #36 - l.append(4) - print(l.__sizeof__()) #36 - l.append(5) - print(l.__sizeof__()) #52 diff --git a/04/dicset.py b/04/dic_set.py similarity index 51% rename from 04/dicset.py rename to 04/dic_set.py index 1bc3c366..d7d6f6d4 100644 --- a/04/dicset.py +++ b/04/dic_set.py @@ -4,133 +4,143 @@ # 根据商品ID求价格,用列表 def find_product_price(products, product_id): - for id, price in products: - if id == product_id: - return price - return None - + for id, price in products: + if id == product_id: + return price + return None + + products = [ - (1, 100), - (2, 400), - (3, 50), - (4, 400) + (1, 100), + (2, 400), + (3, 50), + (4, 400) ] # 更改需求,找出有多少种不同的价格 def find_unique_price(products): - unique_price_list = [] - for _, price in products: - if price not in unique_price_list: - unique_price_list.append(price) - return len(unique_price_list) - - + unique_price_list = [] + for _, price in products: + if price not in unique_price_list: + unique_price_list.append(price) + return len(unique_price_list) + + # 字典版 def find_unique_price_set(products): - unique_price_set = set() - for _, price in products: - unique_price_set.add(price) - return len(unique_price_set) + unique_price_set = set() + for _, price in products: + unique_price_set.add(price) + return len(unique_price_set) if __name__ == "__main__": - # 初始化字典和集合 - d1 = {"name":"jason", "age":20, "gender":"male"} - d2 = dict({"name":"jason", "age":20, "gender":"male"}) + # 初始化字典和集合,字典中元素是有序的,集合中元素是无序的,字典的key是唯一的,集合中的元素也是唯一的 + # 以下方式d1最优,d2次优,d3和d4都很慢 + d1 = {"name": "jason", "age": 20, "gender": "male"} + d2 = dict({"name": "jason", "age": 20, "gender": "male"}) d3 = dict([('name', 'jason'), ('age', 20), ('gender', 'male')]) d4 = dict(name='jason', age=20, gender='male') print(d1 == d2 == d3 == d4) - + s1 = {1, 2, 3} s2 = set([1, 2, 3]) + print(s1) + print(s2) print(s1 == s2) - + # 混合类型 s = {1, "hello", 5.0} print(s) - + # 元素访问 - d = {"name":"zym", "age":20} + d = {"name": "zym", "age": 20} print(d["name"]) print(d.get("age")) print(d.get("locate", "null")) - + + # 集合不支持索引操作,因为集合本质是一个hash表 s = {1, 2, 3} # print(s[1]) #本行出错 - + # 判断元素是否在字典/集合内 s = {1, 2, 3} print(1 in s) print(10 in s) - d = {"name":"zym", "age":20} + d = {"name": "zym", "age": 20} print("name" in d) print("location" in d) - + # 增删查改函数 - d = {"name":"zym", "age":20} - d["gender"] = "male" #增加元素 + d = {"name": "zym", "age": 20} + d["gender"] = "male" # 增加元素 d["dob"] = "1999-02-01" print(d) - d["dob"] = "1998-01-01" #更新键值 + d["dob"] = "1998-01-01" # 更新键值 print(d) - d.pop("dob") #删除键值 + d.pop("dob") # 删除键值 print(d) - + s = {1, 2, 3} - s.add(4) #增加元素 + s.add(4) # 增加元素 + print(s) + s.remove(4) # 删除元素 print(s) - s.remove(4) #删除元素 + # 集合pop()是删除最后⼀个元素,但集合本身是⽆序的,不确定会删除哪个元素,需谨慎使⽤ + s.pop() print(s) - + # 字典排序 - d = {'b':1, 'a':2, 'c':10} - # 根据字典键的升序排序 - d_sorted_by_key = sorted(d.items(), key = lambda x:x[0]) + d = {'b': 1, 'a': 2, 'c': 10} + # 根据字典键的升序排序,sorted返回的是列表 + d_sorted_by_key = sorted(d.items(), key=lambda x: x[0]) print(d_sorted_by_key) # 根据字典值的升序排序 - d_sorted_by_value = sorted(d.items(), key = lambda x:x[1]) + d_sorted_by_value = sorted(d.items(), key=lambda x: x[1]) print(d_sorted_by_value) - - # 对集合排序 + # 如果你在处理超大规模的数据,Python官方推荐使用operator模块,它比lambda 更快 + + # 对集合的元素进⾏升序排序 s = [3, 4, 2, 1] s_sorted = sorted(s) print(s_sorted) - + # 对集合的元素进⾏降序排序 + s_sorted = sorted(s, reverse=True) + print(s_sorted) + # 根据商品ID找商品价格 print("id为2的商品价格为{}".format(find_product_price(products, 2))) - + # 用字典来存储 products_set = { - 1:100, - 2:400, - 3:50, - 4:400} + 1: 100, + 2: 400, + 3: 50, + 4: 400} print("id为3的商品价格为{}".format(products_set[3])) - + # 看商品里有多少种不同的价格? # 列表版, O(N²) - print("不同价格的数目为{}".format( find_unique_price(products))) + print("不同价格的数目为{}".format(find_unique_price(products))) # 字典版,O(N) - print("不同价格的数目为{}".format( find_unique_price_set(products))) - + print("不同价格的数目为{}".format(find_unique_price_set(products))) + # 计算效率 import time - + id = [x for x in range(0, 10000)] price = [x for x in range(20000, 30000)] products = list(zip(id, price)) - + # 计算列表版本的时间 start_using_list = time.perf_counter() find_unique_price(products) end_using_list = time.perf_counter() print("使用列表耗时:{}".format(end_using_list - start_using_list)) - + # 计算字典版本的时间 start_using_set = time.perf_counter() find_unique_price_set(products) end_using_set = time.perf_counter() print("使用列表耗时:{}".format(end_using_set - start_using_set)) - - \ No newline at end of file diff --git a/04/type_check_test.py b/04/type_check_test.py new file mode 100644 index 00000000..201ee390 --- /dev/null +++ b/04/type_check_test.py @@ -0,0 +1,37 @@ +# -*- coding:utf-8 -*- +# 字典和集合中的元素可以是混合类型,虽然很灵活,对于大型项目来说,有时却是灾难 +# 要确定元素类型,可利用类型注解、dataclass来缓解,IDE会提醒,但不强制报错,可通过mypy这类静态检查工具来检查 +# pydantic可强制在运行时报错,更加安全,只是需要安装三方包,更重一些 + +from typing import List, Tuple, Union + +# 明确告诉别人,这个列表里只能有 int 或 str +scores: List[Union[int, str]] = [98, "Absence", 85] +scores.append(32.33) +print(scores) + +# 明确元组的每一项是什么类型 +user_info: Tuple[int, str, float] = (1, "Alice", 9.5) + + +from dataclasses import dataclass + +@dataclass +class User: + id: int + name: str + is_active: bool + +# user = User(1, "张三", True) # 比 [1, "张三", True] 安全得多 +user = User(1, "张三", 22) # 比 [1, "张三", True] 安全得多 +print(user) + +from pydantic import BaseModel + +class User2(BaseModel): + id: int + name: str + is_active: bool + +# 这行在运行时会报错,因为 22 不是 bool +user2 = User2(id=1, name="张三", is_active=22) \ No newline at end of file diff --git a/05/string.py b/05/string_test.py similarity index 81% rename from 05/string.py rename to 05/string_test.py index 7f35653d..c7cb3e4b 100644 --- a/05/string.py +++ b/05/string_test.py @@ -9,7 +9,7 @@ print(name, city, text) # 转义符 - s = "a\nb\tc" + s = "a\nb\tc\vd" print(s) print(len(s)) @@ -51,4 +51,10 @@ print(s.strip()) # 字符串格式化函数 - print("我的名字叫{},年龄{}".format("zym", str(35))) \ No newline at end of file + print("我的名字叫{},年龄{}".format("zym", str(35))) + + name = "Gemini" + age = 1 + # 使用 f-string + message = f"Hello, my name is {name} and I am {age} year old." + print(message) \ No newline at end of file diff --git a/06/inout.py b/06/inout.py index a483a8e3..3371098f 100644 --- a/06/inout.py +++ b/06/inout.py @@ -1,5 +1,5 @@ -#coding:utf-8 -#第6课:输入与输出 +# coding:utf-8 +# 第6课:输入与输出 import re @@ -8,105 +8,104 @@ # 处理文本 def parse(text): - # 去除标点符号和换行 - text = re.sub(r'[^\w ]', ' ', text) - # 转为小写 - text = text.lower() - # 单词列表 - word_list = text.split(' ') - # 去除空白单词 - word_list = filter(None, word_list) - # 生成单词和词频的字典 - word_cnt = {} - for word in word_list: - if word not in word_cnt: - word_cnt[word] = 0 - word_cnt[word] += 1 - - # 按照词频排序 - sorted_word_cnt = sorted(word_cnt.items(), key = lambda kv: kv[1], reverse = True) - return sorted_word_cnt - - + # 去除标点符号和换行 + text = re.sub(r'[^\w ]', ' ', text) + # 转为小写 + text = text.lower() + # 单词列表 + word_list = text.split(' ') + # 去除空白单词 + word_list = filter(None, word_list) + # 生成单词和词频的字典 + word_cnt = {} + for word in word_list: + if word not in word_cnt: + word_cnt[word] = 0 + word_cnt[word] += 1 + + # 按照词频排序 + sorted_word_cnt = sorted(word_cnt.items(), key=lambda kv: kv[1], reverse=True) + return sorted_word_cnt + + # readline版本的parse,练习1 # 处理文本 def parse_readline(infile): - # 生成单词和词频的字典 - word_cnt = {} - while True: - text = infile.readline() - if not text: - break - print(text) - # 去除标点符号和换行 - text = re.sub(r'[^\w ]', ' ', text) - # 转为小写 - text = text.lower() - # 单词列表 - word_list = text.split(' ') - # 去除空白单词 - word_list = filter(None, word_list) - - for word in word_list: - if word not in word_cnt: - word_cnt[word] = 0 - word_cnt[word] += 1 - - # 按照词频排序 - sorted_word_cnt = sorted(word_cnt.items(), key = lambda kv: kv[1], reverse = True) - return sorted_word_cnt - + # 生成单词和词频的字典 + word_cnt = {} + while True: + text = infile.readline() + if not text: + break + print(text) + # 去除标点符号和换行 + text = re.sub(r'[^\w ]', ' ', text) + # 转为小写 + text = text.lower() + # 单词列表 + word_list = text.split(' ') + # 去除空白单词 + word_list = filter(None, word_list) + + for word in word_list: + if word not in word_cnt: + word_cnt[word] = 0 + word_cnt[word] += 1 + + # 按照词频排序 + sorted_word_cnt = sorted(word_cnt.items(), key=lambda kv: kv[1], reverse=True) + return sorted_word_cnt + if __name__ == "__main__": - """ - # 输入 - name = input("姓名:") - gender = input("男的?(y/n)") - - welcome_str = "欢迎来到矩阵空间{prefix}{name}." - welcome_dic = { - "prefix":"Mr." if gender == 'y' else "Mrs.", - "name":name - } - print(welcome_str.format(**welcome_dic)) - - # 输入类型转换 - a = input("输入a:") - b = input("输入b:") - print("a + b ={}".format(a+b)) - print("a的类型为{},b的类型为{}".format(type(a), type(b))) - print("a + b ={}".format(int(a) + int(b))) - """ - # 文件输入输出 - with open("in.txt", "r") as fin: - text = fin.read() - - word_and_freq = parse(text) - - with open("out.txt", "w") as fout: - for word, freq in word_and_freq: - fout.write('{} {}\n'.format(word, freq)) - - # 使用JSON - params = { - "symbol" : "123456", - "type" : "limit", - "price" : 123.4, - "amount" : 23 - } - params_str = json.dumps(params) - print("序列化以后") - print("类型{},值{}".format(type(params_str), params_str)) - - original_params = json.loads(params_str) - print("在去序列化之后") - print("类型{},值{}".format(type(original_params), original_params)) - - # 思考题1 - with open("in.txt", "r") as fin: - word_and_freq = parse_readline(fin) - - with open("out_readline.txt", "w") as fout: - for word, freq in word_and_freq: - fout.write('{} {}\n'.format(word, freq)) - \ No newline at end of file + """ + # 输入 + name = input("姓名:") + gender = input("男的?(y/n)") + + welcome_str = "欢迎来到矩阵空间{prefix}{name}." + welcome_dic = { + "prefix":"Mr." if gender == 'y' else "Mrs.", + "name":name + } + print(welcome_str.format(**welcome_dic)) + + # 输入类型转换 + a = input("输入a:") + b = input("输入b:") + print("a + b ={}".format(a+b)) + print("a的类型为{},b的类型为{}".format(type(a), type(b))) + print("a + b ={}".format(int(a) + int(b))) + """ + # 文件输入输出 + with open("in.txt", "r") as fin: + text = fin.read() + + word_and_freq = parse(text) + + with open("out.txt", "w") as fout: + for word, freq in word_and_freq: + fout.write('{} {}\n'.format(word, freq)) + + # 使用JSON + params = { + "symbol": "123456", + "type": "limit", + "price": 123.4, + "amount": 23 + } + params_str = json.dumps(params) + print("序列化以后") + print("类型{},值{}".format(type(params_str), params_str)) + + original_params = json.loads(params_str) + print("在去序列化之后") + print("类型{},值{}".format(type(original_params), original_params)) + + # 思考题1 + with open("in.txt", "r") as fin: + word_and_freq = parse_readline(fin) + + with open("out_readline.txt", "w") as fout: + for word, freq in word_and_freq: + fout.write('{} {}\n'.format(word, freq)) diff --git a/07/ifloop.py b/07/ifloop.py index 4d06c4e8..06742142 100644 --- a/07/ifloop.py +++ b/07/ifloop.py @@ -3,121 +3,120 @@ if __name__ == "__main__": - # 条件语句 - x = -3 - if x < 0: - y = -x - else: - y = x - print(y) - - # elif语句 - id = 2 - if id == 0: - print("red") - elif id == 1: - print("yellow") - else: - print("green") - - # 循环 - l = [1, 2, 3, 4] - for item in l: - print(item) - - # 字典循环 - d = { - "name":"jason", - "dob":"2000-01-01", - "gender":"male" - } - for k in d: - print(k) - - for v in d.values(): - print(v) - - for k, v in d.items(): - print("keys:{}, values:{}".format(k, v)) - - # 用索引来循环 - l = [1,2,3,4,5,6,7] - for index in range(0, len(l)): - if index < 5: - print(l[index]) - - # 用索引和元素来循环 - l = [1,2,3,4,5,6,7] - for index, item in enumerate(l): - if index < 5: - print(item) - - # break和continue - name_price = {"一":100, - "二":10, - "三":10000} - name_color = {"一":"红", - "二":"蓝", - "三":"红"} - # 不用continue - for name, price in name_price.items(): - if price < 1000: - if name in name_color: - for color in name_color[name]: - if color != "红": - print("name:{}, color:{}".format(name, color)) - else: - print("name:{}, color:{}".format(name, None)) - # 用continue - for name, price in name_price.items(): - if price >= 1000: - continue - if name not in name_color: - print("name:{}, color:{}".format(name, None)) - continue - for color in name_color[name]: - if color == "red": - continue - print("name:{}, color:{}".format(name, color)) - - # while循环 - l = [1,2,3,4] - index = 0 - while index < len(l): - print(l[index]) - index += 1 - - # 测试for和while的效率 - import time - start_for = time.perf_counter() - for i in range(0, 1000000): - pass - end_for = time.perf_counter() - print("for循环{}秒".format(end_for-start_for)) - start_while = time.perf_counter() - i = 0 - while i < 1000000: - i += 1 - end_while = time.perf_counter() - print("while循环{}秒".format(end_while-start_while)) - - # 思考题 - attributes = ['name', 'dob', 'gender'] - values = [ - ['jason', '2000-01-01', 'male'], - ['mike', '1999-01-01', 'male'], - ['nancy', '2001-02-01', 'female'] - ] - # 多行循环语句 - result = [] - for index in range(0, len(values)): - temp = {} - for j in range(3): - temp[attributes[j]]=values[index][j] - result.append(temp) - print(result) - # 一行条件循环语句 抄同学的 - result = [dict(zip(attributes,v)) for v in values] - print(result) + # 条件语句 + x = -3 + if x < 0: + y = -x + else: + y = x + print(y) - \ No newline at end of file + # elif语句 + id = 2 + if id == 0: + print("red") + elif id == 1: + print("yellow") + else: + print("green") + + # 循环 + l = [1, 2, 3, 4] + for item in l: + print(item) + + # 字典循环 + d = { + "name": "jason", + "dob": "2000-01-01", + "gender": "male" + } + for k in d: + print(k) + + for v in d.values(): + print(v) + + for k, v in d.items(): + print("keys:{}, values:{}".format(k, v)) + + # 用索引来循环 + l = [1, 2, 3, 4, 5, 6, 7] + for index in range(0, len(l)): + if index < 5: + print(l[index]) + + # 用索引和元素来循环 + l = [1, 2, 3, 4, 5, 6, 7] + for index, item in enumerate(l): + if index < 5: + print(item) + + # break和continue + name_price = {"一": 100, + "二": 10, + "三": 10000} + name_color = {"一": "红", + "二": "蓝", + "三": "红"} + # 不用continue + for name, price in name_price.items(): + if price < 1000: + if name in name_color: + for color in name_color[name]: + if color != "红": + print("name:{}, color:{}".format(name, color)) + else: + print("name:{}, color:{}".format(name, None)) + # 用continue + for name, price in name_price.items(): + if price >= 1000: + continue + if name not in name_color: + print("name:{}, color:{}".format(name, None)) + continue + for color in name_color[name]: + if color == "red": + continue + print("name:{}, color:{}".format(name, color)) + + # while循环 + l = [1, 2, 3, 4] + index = 0 + while index < len(l): + print(l[index]) + index += 1 + + # 测试for和while的效率 + import time + + start_for = time.perf_counter() + for i in range(0, 1000000): + pass + end_for = time.perf_counter() + print("for循环{}秒".format(end_for - start_for)) + start_while = time.perf_counter() + i = 0 + while i < 1000000: + i += 1 + end_while = time.perf_counter() + print("while循环{}秒".format(end_while - start_while)) + + # 思考题 + attributes = ['name', 'dob', 'gender'] + values = [ + ['jason', '2000-01-01', 'male'], + ['mike', '1999-01-01', 'male'], + ['nancy', '2001-02-01', 'female'] + ] + # 多行循环语句 + result = [] + for index in range(0, len(values)): + temp = {} + for j in range(3): + temp[attributes[j]] = values[index][j] + result.append(temp) + print(result) + # 一行条件循环语句 抄同学的 + result = [dict(zip(attributes, v)) for v in values] + print(result) diff --git a/08/except.py b/08/except.py index 4486c99f..5b32c0a7 100644 --- a/08/except.py +++ b/08/except.py @@ -4,31 +4,30 @@ # 自定义异常类 class MyInputError(Exception): - def __init__(self, value): - self.value = value - - def __str__(self): - return("{} is invalid input".format(repr(self.value))) + def __init__(self, value): + self.value = value + + def __str__(self): + return ("{} is invalid input".format(repr(self.value))) if __name__ == "__main__": - # try except语句 - try: - s = input("输入数字,以,分隔:") - num1 = int(s.split(",")[0].strip()) - num2 = int(s.split(",")[1].strip()) - - except ValueError as err: - print("值错误:{}".format(err)) - except Exception as err: - print("其它异常:{}".format(err)) - - print("继续") - - # 自定义异常 - try: - raise MyInputError(1) - except MyInputError as err: - print("error:{}".format(err)) - print("继续2") - \ No newline at end of file + # try except语句 + try: + s = input("输入数字,以,分隔:") + num1 = int(s.split(",")[0].strip()) + num2 = int(s.split(",")[1].strip()) + + except ValueError as err: + print("值错误:{}".format(err)) + except Exception as err: + print("其它异常:{}".format(err)) + + print("继续") + + # 自定义异常 + try: + raise MyInputError(1) + except MyInputError as err: + print("error:{}".format(err)) + print("继续2") diff --git a/08/except2.py b/08/except2.py new file mode 100644 index 00000000..de50dbe7 --- /dev/null +++ b/08/except2.py @@ -0,0 +1,12 @@ +# coding:utf-8 + +# 如果你在异常处理的except block中,把异常赋予了⼀个变量,那么这个变量会在except block执⾏结束时被删除 +# 也就是说在异常所指向的那个变量会在finally中删除,因此⼀定要保证except中异常赋予的变量,在之后的语句中不再被⽤到 +# 异常变量作用域清理:异常变量的作用域仅限于except块内部 +e = 1 +try: + 1 / 0 +except ZeroDivisionError as e: + pass + +print(e) # 这一行会报错:NameError: name 'e' is not defined diff --git a/09/fun.py b/09/fun.py index 5ccfad6f..d1d19f6c 100644 --- a/09/fun.py +++ b/09/fun.py @@ -3,114 +3,139 @@ # 调用另一个函数 def func(message): - my_func(message) + my_func(message) -def my_func(message): - print("收到一个消息:{}".format(message)) +def my_func(message): + print("收到一个消息:{}".format(message)) if __name__ == "__main__": - my_func("hello world!") - - # 函数嵌套 - def my_sum(a, b): - return a+b - - result = my_sum(3, 5) - print(result) - - def find_largest_element(l): - if not isinstance(l, list): - print("输入数据不是列表") - return - if len(l) == 0: - print("列表为空") - return - largest_element = l[0] - for item in l: - if item > largest_element: - largest_element = item - print("列表中最大元素为:{}".format(largest_element)) - - find_largest_element([3, -5, 6, 8, 2, 1]) - - func("你好,python") - - # 参数的多态性 - print(my_sum([1, 2], [3, 4])) - print("hell", " world") - try: - my_sum(5, "7") - except Exception as err: - print("发生错误!{}".format(err)) - - # 函数嵌套提高效率 - def factorial(input): - # 输入检查,只运行一次 - if not isinstance(input, int): - raise Exception("必须输入整数") - if input < 0: - raise Exception("输入必须大于等于0") - - # 实际计算 - def inner_factorial(input): - if input <= 1: - return 1 - return input*inner_factorial(input-1) - - return(inner_factorial(input)) - - try: - print(factorial(12)) - except Exception as err: - print(err) - - # 函数中改变外部变量 - value = 2 - overvalue = 3 - def changeValue(): - global value - value += 1 - overvalue = 6 - print(value, overvalue) - changeValue() - print(value) - - # 嵌套函数内部修改 - # 加nonlocal - print("加nonlocal") - def outer(): - x = 3 - def inner(): - nonlocal x - x = 5 - print("内部", x) - print("外部", x) - inner() - print("外部", x) - outer() - # 不加 - print("不加") - def outer2(): - x = 3 - def inner2(): - x = 5 - print("内部", x) - print("外部", x) - inner2() - print("外部", x) - outer2() - - # 闭包,计算n次幂 - def nth_power(exp): - def exponent_of(base): - return base**exp - return exponent_of - - square = nth_power(2) - cube = nth_power(3) - - print(square(2)) - print(cube(2)) - \ No newline at end of file + print(range(10)) + r = list(range(10)) + print(r) + my_func("hello world!") + + + # 函数嵌套 + def my_sum(a, b): + return a + b + + + result = my_sum(3, 5) + print(result) + + + def find_largest_element(l): + if not isinstance(l, list): + print("输入数据不是列表") + return + if len(l) == 0: + print("列表为空") + return + largest_element = l[0] + for item in l: + if item > largest_element: + largest_element = item + print("列表中最大元素为:{}".format(largest_element)) + + + find_largest_element([3, -5, 6, 8, 2, 1]) + + func("你好,python") + + # 参数的多态性 + print(my_sum([1, 2], [3, 4])) + print("hell", " world") + try: + my_sum(5, "7") + except Exception as err: + print("发生错误!{}".format(err)) + + + # 函数嵌套提高效率 + def factorial(input): + # 输入检查,只运行一次 + if not isinstance(input, int): + raise Exception("必须输入整数") + if input < 0: + raise Exception("输入必须大于等于0") + + # 实际计算 + def inner_factorial(input): + if input <= 1: + return 1 + return input * inner_factorial(input - 1) + + return (inner_factorial(input)) + + + try: + print(factorial(12)) + except Exception as err: + print(err) + + # 函数中改变外部变量 + value = 2 + overvalue = 3 + + def changeValue(): + global value + value += 1 + overvalue = 6 + print(value, overvalue) + + changeValue() + print(value) + + # 嵌套函数内部修改 + # 加nonlocal + print("加nonlocal") + + + def outer(): + x = 3 + + def inner(): + nonlocal x + x = 5 + print("内部", x) + + print("外部", x) + inner() + print("外部", x) + + + outer() + # 不加 + print("不加") + + + def outer2(): + x = 3 + + def inner2(): + x = 5 + print("内部", x) + + print("外部", x) + inner2() + print("外部", x) + + + outer2() + + + # 闭包,计算n次幂 + def nth_power(exp): + def exponent_of(base): + return base ** exp + + return exponent_of + + + square = nth_power(2) + cube = nth_power(3) + + print(square(2)) + print(cube(2)) diff --git a/10/button.py b/10/button.py index 08aeaca0..3bfab517 100644 --- a/10/button.py +++ b/10/button.py @@ -4,8 +4,8 @@ from tkinter import Button, mainloop button = Button( - text = "This is a button", - command = lambda : print("being pressed") + text="This is a button", + command=lambda: print("being pressed") ) button.pack() -mainloop() \ No newline at end of file +mainloop() diff --git a/10/nmfun.py b/10/nmfun.py index b8cc2141..25a084cd 100644 --- a/10/nmfun.py +++ b/10/nmfun.py @@ -3,52 +3,65 @@ if __name__ == "__main__": - # lambda表达式 - square = lambda x:x**2 - print(square(3)) - - # 列表内部使用 - l = [(lambda x:x**2)(x) for x in range(10)] - print(l) - - # 用作函数参数 - l = [(1, 20), (3, 0), (9, 10), (2, -1)] - l.sort(key = lambda x:x[1]) - print(l) - - # 让程序简洁 - squares = map(lambda x:x**2, [1,2,3,4,5]) - print(list(squares)) - - # 函数式编程,将列表元素加倍 - def mutiply_2_pure(l): - new_list = [] - for item in l: - new_list.append(item*2) - return new_list - - print(mutiply_2_pure([1,2,3,4])) - - # map函数 - l = [1,3,5,6,8] - new_list = list(map(lambda x:x**2, l)) - print(new_list) - - # filter函数,返回列表中所有偶数 - l = [1,2,3,4,5,6,7,8,9] - new_list = filter(lambda x:x%2 == 0, l) - print(list(new_list)) - - # reduce函数 计算阶乘 - from functools import reduce - product = reduce(lambda x, y:x*y, l) - print(product) - - # 思考题 - # 1 将字典按值从大到小排序 - import operator - d = {"mike":10, "lucy":2, "ben":30} - print(d.items()) - sort_d = sorted(d.items(), key=operator.itemgetter(1), reverse=True) - print(sort_d) - + # lambda表达式 + square = lambda x: x ** 2 + print(square(3)) + + # 列表内部使用 + l = [(lambda x: x ** 2)(x) for x in range(10)] + print(l) + + # 用作函数参数 + l = [(1, 20), (3, 0), (9, 10), (2, -1)] + l.sort(key=lambda x: x[1]) + print(l) + + # 让程序简洁 + squares = map(lambda x: x ** 2, [1, 2, 3, 4, 5]) + print(list(squares)) + + + # 函数式编程,map()、filter()和reduce(),通常结合匿名函数lambda⼀起使⽤ + # 将列表元素加倍 + def mutiply_2_pure(l): + new_list = [] + for item in l: + new_list.append(item * 2) + return new_list + + + print(mutiply_2_pure([1, 2, 3, 4])) + + # map函数 + l = [1, 3, 5, 6, 8] + new_list = list(map(lambda x: x ** 2, l)) + print(new_list) + + # filter函数,返回列表中所有偶数 + l = [1, 2, 3, 4, 5, 6, 7, 8, 9] + new_list = filter(lambda x: x % 2 == 0, l) + print(list(new_list)) + + # reduce函数 计算阶乘 + from functools import reduce + + product = reduce(lambda x, y: x * y, l) + print(product) + + # 思考题 + # 1 将字典按值从大到小排序 + import operator + + d = {"mike": 10, "lucy": 2, "ben": 30} + print(d.items()) + # print(sorted(d.items(), key=lambda x: x[1], reverse=True)) + sort_d = sorted(d.items(), key=operator.itemgetter(1), reverse=True) + print(sort_d) + + # 计算列表之和 (代替 lambda x, y: x + y) + res = reduce(operator.add, [1, 2, 3, 4]) # 10 + + # 计算阶乘 (代替 lambda x, y: x * y) + res = reduce(operator.mul, [1, 2, 3, 4]) # 24 + + # 其他:sub(-), truediv(/), floordiv(//), mod(%), pow(**) diff --git a/11/class.py b/11/class.py index 922d1518..27e9f766 100644 --- a/11/class.py +++ b/11/class.py @@ -4,150 +4,157 @@ # 类 class Document(): - def __init__(self, title, author, context): - print("调用初始函数!") - self.title = title - self.author = author - self.__context = context #私有属性 - - def get_context_length(self): - return len(self.__context) - - def intercept_context(self, length): - self.__context = self.__context[:length] - - + def __init__(self, title, author, context): + print("调用初始函数!") + self.title = title + self.author = author + self.__context = context # 私有属性 + + def get_context_length(self): + return len(self.__context) + + def intercept_context(self, length): + self.__context = self.__context[:length] + + # 类2 class Document2(): - WELCOME_STR = "欢迎,本书的内容为{}." - - def __init__(self, title, author, context): - print("调用初始函数!") - self.title = title - self.author = author - self.__context = context #私有属性 - - # 类函数 - @classmethod - def create_empty_book(cls, title, author): - return cls(title=title, author=author, context="nothing") - - # 成员函数 - def get_context_length(self): - return len(self.__context) - - # 静态函数 - @staticmethod - def get_welcome(context): - return Document2.WELCOME_STR.format(context) - + WELCOME_STR = "欢迎,本书的内容为{}." + + def __init__(self, title, author, context): + print("调用初始函数!") + self.title = title # 实例属性 + self.author = author + self.__context = context # 私有属性 + + # 类函数 + @classmethod + def create_empty_book(cls, title, author): + return cls(title=title, author=author, context="nothing") + + # 成员函数 + def get_context_length(self): + return len(self.__context) + + # 静态函数 + @staticmethod + def get_welcome(context): + return Document2.WELCOME_STR.format(context) + + # 类的继承 class Entity(): - def __init__(self, object_type): - print("父类构造函数") - self.object_type = object_type - - def get_contex_length(self): - raise Exception("没有定义get_context_length") - - def print_title(self): - print(self.title) - - + def __init__(self, object_type): + print("父类构造函数") + self.object_type = object_type + + def get_context_length(self): + raise Exception("没有定义get_context_length") + + def print_title(self): + print(self.title) + + class Document3(Entity): - def __init__(self, title, author, context): - Entity.__init__(self, "document") - print("Document3调用初始函数!") - self.title = title - self.author = author - self.__context = context - - def get_context_length(self): - return len(self.__context) - + def __init__(self, title, author, context): + Entity.__init__(self, "document") + print("Document3调用初始函数!") + self.title = title + self.author = author + self.__context = context + + def get_context_length(self): + return len(self.__context) + + class Video(Entity): - def __init__(self, title, author, video_length): - Entity.__init__(self, "video") - print("video调用初始函数!") - self.title = title - self.author = author - self.__video_length = video_length - - def get_context_length(self): - return self.__video_length - + def __init__(self, title, author, video_length): + Entity.__init__(self, "video") + print("video调用初始函数!") + self.title = title + self.author = author + self.__video_length = video_length + + def get_context_length(self): + return self.__video_length + # 抽象函数和抽象类 from abc import ABCMeta, abstractmethod -class Entity2(metaclass = ABCMeta): - @abstractmethod - def get_title(self): - pass - - @abstractmethod - def set_title(self, title): - pass - + + +class Entity2(metaclass=ABCMeta): + @abstractmethod + def get_title(self): + pass + + @abstractmethod + def set_title(self, title): + pass + class Document4(Entity2): - def get_title(self): - return self.title - - def set_title(self, title): - self.title = title - - + def get_title(self): + return self.title + + def set_title(self, title): + self.title = title + + # 思考题 class A(): - def __init__(self): - print("A") - + def __init__(self): + print("A") + + class B(A): - def __init__(self): - A.__init__(self) - print("B") - + def __init__(self): + A.__init__(self) + print("B") + + class C(A): - def __init__(self): - A.__init__(self) - print("C") - + def __init__(self): + A.__init__(self) + print("C") + + class D(B, C): - def __init__(self): - B.__init__(self) - C.__init__(self) - print("D") + def __init__(self): + B.__init__(self) + C.__init__(self) + print("D") + if __name__ == "__main__": - harry_potter_book = Document("hp", "J.K.Rowling", "aabbccgfdghhddee") - - print(harry_potter_book.title) - print(harry_potter_book.author) - print(harry_potter_book.get_context_length()) - harry_potter_book.intercept_context(10) - print(harry_potter_book.get_context_length()) - # print(harry_potter_book.__context) - - empty_book = Document2.create_empty_book("aaaaa", "bbbbb") - print(empty_book.get_context_length()) - print(empty_book.get_welcome("indeed nothing")) - - # 类继承 - hp_book = Document3("a", "aa", "aaa") - hp_movie = Video("b", "bb", 30) - - print(hp_book.object_type) - print(hp_movie.object_type) - - print(hp_book.get_context_length()) - print(hp_movie.get_context_length()) - - # 抽象类 - document = Document4() - document.set_title("hp") - print(document.get_title()) - - # entity = Entity2() - # 思考题 - d = D() - \ No newline at end of file + harry_potter_book = Document("hp", "J.K.Rowling", "aabbccgfdghhddee") + + print(harry_potter_book.title) + print(harry_potter_book.author) + print(harry_potter_book.get_context_length()) + harry_potter_book.intercept_context(10) + print(harry_potter_book.get_context_length()) + # print(harry_potter_book.__context) + + empty_book = Document2.create_empty_book("aaaaa", "bbbbb") + print(empty_book.get_context_length()) + print(empty_book.get_welcome("indeed nothing")) + + # 类继承 + hp_book = Document3("a", "aa", "aaa") + hp_movie = Video("b", "bb", 30) + + print(hp_book.object_type) + print(hp_movie.object_type) + + print(hp_book.get_context_length()) + print(hp_movie.get_context_length()) + + # 抽象类 + document = Document4() + document.set_title("hp") + print(document.get_title()) + + # entity = Entity2() + # 思考题 + d = D() diff --git a/12/search.py b/12/search.py index d0fde773..f39dae12 100644 --- a/12/search.py +++ b/12/search.py @@ -4,194 +4,199 @@ # 搜索引擎基类 class SearchEngineBase(object): - def __init__(self): - print("父类") - - def add_corpus(self, file_path): - with open(file_path, "r") as fin: - text = fin.read() - self.process_corpus(file_path, text) - - def process_corpus(self, id, text): - raise Exception("process_corpus未定义") - - def search(self, query): - raise Exception("search未定义") - - + def __init__(self): + print("父类") + + def add_corpus(self, file_path): + with open(file_path, "r") as fin: + text = fin.read() + self.process_corpus(file_path, text) + + def process_corpus(self, id, text): + raise Exception("process_corpus未定义") + + def search(self, query): + raise Exception("search未定义") + + def main(search_engine): - for file_path in ["1.txt", "2.txt", "3.txt", "4.txt"]: - search_engine.add_corpus(file_path) - - while True: - query = input("输入检索词,输q结束:") - if query == "q": - break - results = search_engine.search(query) - print("found {} result(s):".format(len(results))) - - for result in results: - print(result) - - + for file_path in ["1.txt", "2.txt", "3.txt", "4.txt"]: + search_engine.add_corpus(file_path) + + while True: + query = input("输入检索词,输q结束:") + if query == "q": + break + results = search_engine.search(query) + print("found {} result(s):".format(len(results))) + + for result in results: + print(result) + + # 简单的搜索引擎 class SimpleEngine(SearchEngineBase): - def __init__(self): - super(SimpleEngine, self).__init__() - print("子类") - self.__id_to_texts = {} - - def process_corpus(self, id, text): - self.__id_to_texts[id] = text - - def search(self, query): - results = [] - for id, text in self.__id_to_texts.items(): - if query in text: - results.append(id) - return results + def __init__(self): + super(SimpleEngine, self).__init__() + print("子类") + self.__id_to_texts = {} + + def process_corpus(self, id, text): + self.__id_to_texts[id] = text + + def search(self, query): + results = [] + for id, text in self.__id_to_texts.items(): + if query in text: + results.append(id) + return results # 分词的搜索引擎 import re + class BOWEngine(SearchEngineBase): - def __init__(self): - super(BOWEngine, self).__init__() - self.__id_to_word = {} - - def process_corpus(self, id, text): - self.__id_to_word[id] = self.parse_text_to_word(text) - - def search(self, query): - query_words = self.parse_text_to_word(query) - results = [] - for id, words in self.__id_to_word.items(): - if self.query_match(query_words, words): - results.append(id) - return results - - @staticmethod - def parse_text_to_word(text): - # 使用正则表达式去除标点和换行符 - text = re.sub(r'[^\w ]', ' ', text) - # 转为小写 - text = text.lower() - # 生成所有单词的列表 - word_list = text.split(' ') - # 去除空白单词 - word_list = filter(None, word_list) - # 返回单词的set - return set(word_list) - - @staticmethod - def query_match(query_words, words): - for query_word in query_words: - if query_word not in words: - return False - return True + def __init__(self): + super(BOWEngine, self).__init__() + self.__id_to_word = {} + + def process_corpus(self, id, text): + self.__id_to_word[id] = self.parse_text_to_word(text) + + def search(self, query): + query_words = self.parse_text_to_word(query) + results = [] + for id, words in self.__id_to_word.items(): + if self.query_match(query_words, words): + results.append(id) + return results + + @staticmethod + def parse_text_to_word(text): + # 使用正则表达式去除标点和换行符 + text = re.sub(r'[^\w ]', ' ', text) + # 转为小写 + text = text.lower() + # 生成所有单词的列表 + word_list = text.split(' ') + # 去除空白单词 + word_list = filter(None, word_list) + # 返回单词的set + return set(word_list) + + @staticmethod + def query_match(query_words, words): + for query_word in query_words: + if query_word not in words: + return False + return True + # 减少查询的量 class BOWInvertedIndexEngine(SearchEngineBase): - def __init__(self): - super(BOWInvertedIndexEngine, self).__init__() - self.inverted_index = {} - - def process_corpus(self, id, text): - words = self.parse_text_to_word(text) - for word in words: - if word not in self.inverted_index: - self.inverted_index[word] = [] - self.inverted_index[word].append(id) - - def search(self, query): - query_words = list(self.parse_text_to_word(query)) - query_words_index = list() - for query_word in query_words: - query_words_index.append(0) - - # 如果某一单词倒序索引,立即返回 - for query_word in query_words: - if query_word not in self.inverted_index: - return [] - - result = [] - while True: - # 首先获得当前状态下所有倒序索引的index - current_ids = [] - for idx, query_word in enumerate(query_words): - current_index = query_words_index[idx] - current_inverted_list = self.inverted_index[query_word] - # 已经遍历到某个倒序索引的末尾,结束 - if current_index >= len(current_inverted_list): - return result - current_ids.append(current_inverted_list[current_index]) - - # 然后,如果 current_ids 的所有元素都一样,那么表明这个单词在这个元素对应的文档中都出现了 - if all(x == current_ids[0] for x in current_ids): - result.append(current_ids[0]) - query_words_index = [x+1 for x in query_words_index] - continue - - # 如果不是,把最小元素加1 - min_val = min(current_ids) - min_val_pos = current_ids.index(min_val) - query_words_index[min_val_pos] += 1 - - @staticmethod - def parse_text_to_word(text): - # 使用正则表达式去除标点和换行符 - text = re.sub(r'[^\w ]', ' ', text) - # 转为小写 - text = text.lower() - # 生成所有单词的列表 - word_list = text.split(' ') - # 去除空白单词 - word_list = filter(None, word_list) - # 返回单词的set - return set(word_list) + def __init__(self): + super(BOWInvertedIndexEngine, self).__init__() + self.inverted_index = {} + + def process_corpus(self, id, text): + words = self.parse_text_to_word(text) + for word in words: + if word not in self.inverted_index: + self.inverted_index[word] = [] + self.inverted_index[word].append(id) + + def search(self, query): + query_words = list(self.parse_text_to_word(query)) + query_words_index = list() + for query_word in query_words: + query_words_index.append(0) + + # 如果某一单词倒序索引,立即返回 + for query_word in query_words: + if query_word not in self.inverted_index: + return [] + + result = [] + while True: + # 首先获得当前状态下所有倒序索引的index + current_ids = [] + for idx, query_word in enumerate(query_words): + current_index = query_words_index[idx] + current_inverted_list = self.inverted_index[query_word] + # 已经遍历到某个倒序索引的末尾,结束 + if current_index >= len(current_inverted_list): + return result + current_ids.append(current_inverted_list[current_index]) + + # 然后,如果 current_ids 的所有元素都一样,那么表明这个单词在这个元素对应的文档中都出现了 + if all(x == current_ids[0] for x in current_ids): + result.append(current_ids[0]) + query_words_index = [x + 1 for x in query_words_index] + continue + + # 如果不是,把最小元素加1 + min_val = min(current_ids) + min_val_pos = current_ids.index(min_val) + query_words_index[min_val_pos] += 1 + + @staticmethod + def parse_text_to_word(text): + # 使用正则表达式去除标点和换行符 + text = re.sub(r'[^\w ]', ' ', text) + # 转为小写 + text = text.lower() + # 生成所有单词的列表 + word_list = text.split(' ') + # 去除空白单词 + word_list = filter(None, word_list) + # 返回单词的set + return set(word_list) # 缓存和多重继承 import pylru + class LRUCache(object): - def __init__(self, size = 2): - self.cache = pylru.lrucache(size) - - def has(self, key): - return key in self.cache - - def get(self, key): - return self.cache[key] - - def set(self, key, value): - self.cache[key] = value - + def __init__(self, size=32): + self.cache = pylru.lrucache(size) + + def has(self, key): + return key in self.cache + + def get(self, key): + return self.cache[key] + + def set(self, key, value): + self.cache[key] = value + class BOWInvertedIndexEngineWithCache(BOWInvertedIndexEngine, LRUCache): - def __init__(self): - super(BOWInvertedIndexEngineWithCache, self).__init__() - LRUCache.__init__(self) - - def search(self, query): - if self.has(query): - print("缓存命中!") - return self.get(query) - - result = super(BOWInvertedIndexEngineWithCache, self).search(query) - self.set(query, result) - - return result + def __init__(self): + # 直接初始化该类的第⼀个⽗类,要求继承链的昀顶层⽗类必须要继承 object + super(BOWInvertedIndexEngineWithCache, self).__init__() + # 多重继承,如果有多个构造函数需要调⽤,必须⽤传统的⽅法 + LRUCache.__init__(self) + + def search(self, query): + if self.has(query): + print("缓存命中!") + return self.get(query) + + # Python3.x和Python2.x的⼀个区别是: Python3可以使⽤直接使⽤ super().xxx代替super(Class, self).xxx + result = super(BOWInvertedIndexEngineWithCache, self).search(query) + self.set(query, result) + + return result if __name__ == "__main__": - # search_engine = SimpleEngine() - # main(search_engine) - # search_engine = BOWEngine() - # main(search_engine) - # search_engine = BOWInvertedIndexEngine() - # main(search_engine) - search_engine = BOWInvertedIndexEngineWithCache() - main(search_engine) - \ No newline at end of file + # search_engine = SimpleEngine() + # main(search_engine) + # search_engine = BOWEngine() + # main(search_engine) + search_engine = BOWInvertedIndexEngine() + main(search_engine) + # search_engine = BOWInvertedIndexEngineWithCache() + # main(search_engine) diff --git a/13/main.py b/13/main.py index 5036c9d5..8b077be2 100644 --- a/13/main.py +++ b/13/main.py @@ -6,14 +6,12 @@ from utils.class_utils import * from utils.utils import * +# from your_file import function_name, class_name +if __name__ == "__main__": + print(get_sum(1, 2)) + encoder = Encoder() + decoder = Decoder() -if __name__ == "__main__": - print(get_sum(1, 2)) - - encoder = Encoder() - decoder = Decoder() - - print(encoder.encode("abcde")) - print(decoder.decode("edcba")) - \ No newline at end of file + print(encoder.encode("abcde")) + print(decoder.decode("edcba")) diff --git a/13/src/sub_main2.py b/13/src/sub_main2.py new file mode 100644 index 00000000..63ec298e --- /dev/null +++ b/13/src/sub_main2.py @@ -0,0 +1,19 @@ +# coding:utf-8 +# 第13课 Python模块化 + +import sys +sys.path.append("..") + +import utils.class_utils +import utils.utils +# from module_name import * 和 import module_name的区别就是:前者访问必须带前缀:module_name.func(),后者可直接调用:func(), +# 后者会导致命令冲突,以及不知道该方法出自哪里,推荐第一种方式。还有一种from module_name import class_name也可以 + +if __name__ == "__main__": + print(utils.utils.get_sum(1, 2)) + + encoder = utils.class_utils.Encoder() + decoder = utils.class_utils.Decoder() + + print(encoder.encode("abcde")) + print(decoder.decode("edcba")) diff --git a/13/test1/src/main.py b/13/test1/src/main.py index 6baac0d9..1626c1ef 100644 --- a/13/test1/src/main.py +++ b/13/test1/src/main.py @@ -2,11 +2,13 @@ # 第13课 Python模块化 # src/main.py import sys -sys.path.append("..") +print(sys.path) +# sys.path.append("..")表示将当前程序所在位置向上提了⼀级,之后就能调⽤ utils 的模块了 +# 利用sys.path.append("..")可以改变当前Python解释器的位置。不过,不推荐这种方式,固定⼀个确定路径对⼤型⼯程来说是⾮常必要的 from proto.mat import Matrix from utils.mat_mul import mat_mul -a = Matrix([[1,2], [3,4]]) -b = Matrix([[5,6], [7,8]]) +a = Matrix([[1, 2], [3, 4]]) +b = Matrix([[5, 6], [7, 8]]) -print(mat_mul(a, b).data) \ No newline at end of file +print(mat_mul(a, b).data) diff --git a/13/utils/class_utils.py b/13/utils/class_utils.py index 4bc94506..531cdaf1 100644 --- a/13/utils/class_utils.py +++ b/13/utils/class_utils.py @@ -1,12 +1,14 @@ # coding:utf-8 # 第13课 Python模块化 +def ddd(): + pass + class Encoder(object): - def encode(self, s): - return s[::-1] - - + def encode(self, s): + return s[::-1] + + class Decoder(object): - def decode(self, s): - return ' '.join(reversed(list(s))) - \ No newline at end of file + def decode(self, s): + return ' '.join(reversed(list(s))) diff --git a/15/obcopy.py b/15/obcopy.py index 6be03b4e..6885900a 100644 --- a/15/obcopy.py +++ b/15/obcopy.py @@ -3,79 +3,88 @@ import copy - if __name__ == "__main__": - a = 2 - b = 2 - print(a == b) - print(a is b) - print("id(a) = {}".format(id(a))) - print("id(b) = {}".format(id(b))) - # 以上只对-5至256的值有效 - a = 10000000 - b = 10000000 - print(a == b) - print(a is b) - print("id(a) = {}".format(id(a))) - print("id(b) = {}".format(id(b))) - - # 对于不可变变量 - t1 = (1, 2, [3, 4]) - t2 = (1, 2, [3, 4]) - print(t1 == t2) - print(id(t1), id(t2)) - t1[-1].append(5) - print(t1 == t2) - print(id(t1), id(t2)) - - # 浅拷贝 - l1 = [1, 2, 3] - l2 = list(l1) - print(l1 == l2) - print(l1 is l2) - s1 = set([1, 2, 3]) - s2 = set(s1) - print(s1, s2) - print(s1 == s2) - print(s1 is s2) - # 通过切片操作 - l1 = [1, 2, 3] - l2 = l1[:] - print(l1 == l2) - print(l1 is l2) - # 使用copy函数 - l2 = copy.copy(l1) - print(l1 == l2) - print(l1 is l2) - # 元组的不同,返回一个指向元组的引用 - t1 = (1,2,3) - t2 = tuple(t1) - print(t1 == t2) - print(t1 is t2) - - # 浅拷贝的副作用 - l1 = [[1, 2], (30, 40)] - l2 = list(l1) - l1.append(100) - l1[0].append(3) - print(l1) - print(l2) - l1[1] += (50, 60) - print(l1) - print(l2) - - # 深拷贝 - l1 = [[1, 2], (30, 40)] - l2 = copy.deepcopy(l1) - l1.append(100) - l1[0].append(3) - print(l1, l2) - # 陷入无限循环的深拷贝 - x = [1] - x.append(x) - print(x) - y = copy.deepcopy(x) - print(y) - # 思考题 - # print(x == y) #报错 - print(x is y) \ No newline at end of file + a = 2 + b = 2 + # '==' 操作符⽐较对象之间的值是否相等 + print(a == b) + # 'is' 操作符⽐较的是对象的身份标识是否相等,即它们是否是同⼀个对象,是否指向同⼀个内存地址 + print(a is b) + # 对象的身份标识,都能通过函数id(object)获得 + print("id(a) = {}".format(id(a))) + print("id(b) = {}".format(id(b))) + # 对于整型数字来说,a is b为True的结论,因为Python会自动缓存范围在 [-5, 256] 之间的整数,因此这个范围内的同一个数字都使用同一个内存地址。 + # 超过这个范围就要看运行环境:如果在交互式或Jupyter中执行,每行代码是单独编译的,因此a和b是独立的对象,就不相等。 + # 而如果是脚本中,python会使用“常量折叠”优化的技术,此时a和b指向同一个对象。 + a = 10000000 + b = 10000000 + print(a == b) + print(a is b) + print("id(a) = {}".format(id(a))) + print("id(b) = {}".format(id(b))) + # 永远不要用 is 来比较数值或字符串的内容。 + # is 应该只用于检查一个变量是否为 None (例如 if x is None:),或者检查两个变量是否确实是同一个实例(单例模式)。 + + # 对于不可变变量 + t1 = (1, 2, [3, 4]) + t2 = (1, 2, [3, 4]) + print(t1 == t2) + print(id(t1), id(t2)) + t1[-1].append(5) + print(t1 == t2) + print(id(t1), id(t2)) + + # 浅拷贝:是指重新分配⼀块内存,创建⼀个新的对象,⾥⾯的元素是原对象中⼦对象的引⽤ + l1 = [1, 2, 3] + l2 = list(l1) + print(l1 == l2) + print(l1 is l2) + s1 = set([1, 2, 3]) + s2 = set(s1) + print(s1, s2) + print(s1 == s2) + print(s1 is s2) + # 通过切片操作 + l1 = [1, 2, 3] + l2 = l1[:] + print(l1 == l2) + print(l1 is l2) + # 使用copy函数 + l2 = copy.copy(l1) + print(l1 == l2) + print(l1 is l2) + # 元组的不同,返回一个指向元组的引用 + t1 = (1, 2, 3) + t2 = tuple(t1) + print(t1 == t2) + print(t1 is t2) + + # 浅拷贝的副作用 + l1 = [[1, 2], (30, 40)] + l2 = list(l1) + l1.append(100) + l1[0].append(3) + print(l1) + print(l2) + l1[1] += (50, 60) + print(l1) + print(l2) + + # 深拷贝 + l1 = [[1, 2], (30, 40)] + l2 = copy.deepcopy(l1) + l1.append(100) + l1[0].append(3) + print(l1, l2) + # 陷入无限循环的深拷贝 + x = [1] + # 把 x 这个对象本身的引用(内存地址)添加到了它自己的末尾 + x.append(x) + print(x) + y = copy.deepcopy(x) + print(y) + + # 思考题 + # == 比较会比较所有元素是否相等,而x和y都是无限循环引用的对象,会报超出递归深度错误 + # print(x == y) # 报错:RecursionError: maximum recursion depth exceeded in comparison + print(x is y) diff --git a/16/canshu.py b/16/canshu.py index d6d645c4..c689e8b3 100644 --- a/16/canshu.py +++ b/16/canshu.py @@ -3,63 +3,79 @@ if __name__ == "__main__": - # 变量及赋值 - a = 1 - b = a - a = a + 1 - print(a, b) - # 列表赋值 - l1 = [1,2,3] - l2 = l1 - l1.append(4) - print(l1) - print(l2) - - # 函数参数传递 - def my_func1(b): - b = 2 - - a = 1 - my_func1(a) - print(a) - - def my_func2(b): - b = 2 - return b - - a = my_func2(a) - print(a) - # 传入可变对象 - def my_func3(l2): - l2.append(4) - l1 = [1,2,3] - my_func3(l1) - print(l1) - # 参数原值不变 - def my_func4(l2): - l2 = l2 + [4] - l1 = [1,2,3] - my_func4(l1) - print(l1) - # 要改变参数原值的做法 - def my_func5(l2): - l2 = l2 + [4] - return l2 - l1 = [1,2,3] - l1 = my_func5(l1) - print(l1) - - # 思考题1 - l1 = [1,2,3,4] - l2 = [1,2,3,4] - l3 = l2 - print(id(l1), id(l2), id(l3)) - # 思考题2 - def func(d): - d["a"] = 10 - d["b"] = 20 - - d = {"a":1, "b":2} - func(d) - print(d) - \ No newline at end of file + # 变量及赋值 + a = 1 + # 简单的赋值b = a,并不表示重新创建了新对象,只是让同⼀个对象被多个变量指向或引⽤ + b = a + # 因为a是不可变对象,a + 1其实会新建一个对象2,然后a指向它 + a = a + 1 + print(a, b) + # 列表赋值 + l1 = [1, 2, 3] + l2 = l1 + # 因为l1是可变对象,因此不会新建对象 + l1.append(4) + print(l1) + print(l2) + + # 函数参数传递 + def my_func1(b): + b = 2 + + + a = 1 + my_func1(a) + print(a) + + + def my_func2(b): + b = 2 + return b + + + a = my_func2(a) + print(a) + + # 传入可变对象 + def my_func3(l2): + l2.append(4) + + + l1 = [1, 2, 3] + my_func3(l1) + print(l1) + + # 参数原值不变 + def my_func4(l2): + l2 = l2 + [4] + + + l1 = [1, 2, 3] + my_func4(l1) + print(l1) + + # 要改变参数原值的做法 + def my_func5(l2): + l2 = l2 + [4] + return l2 + + + l1 = [1, 2, 3] + l1 = my_func5(l1) + print(l1) + + # 思考题1 + l1 = [1, 2, 3, 4] + l2 = [1, 2, 3, 4] + l3 = l2 + print(id(l1), id(l2), id(l3)) + + # 思考题2 + def func(d): + d["a"] = 10 + d["b"] = 20 + + + d = {"a": 1, "b": 2} + func(d) + print(d) diff --git a/17/zsq.py b/17/zsq.py index fe380bf0..c8e20d26 100644 --- a/17/zsq.py +++ b/17/zsq.py @@ -5,139 +5,183 @@ import functools import time - if __name__ == "__main__": - # 函数作为变量 - def func(message): - print("收到一个消息:{}".format(message)) - - send_message = func - send_message("hello world") - - # 函数作为参数 - def root_call(fun, message): - print(fun(message)) - - root_call(func, "函数参数") - - # 函数嵌套 - def fund(message): - def get_message(message): - print("收到一个消息:{}".format(message)) - return get_message(message) - - fund("函数嵌套") - - # 闭包 - def func_closure(): - def get_message(message): - print("收到一个消息:{}".format(message)) - return get_message - - send_message = func_closure() - send_message("返回函数对象(闭包)") - - # 简单装饰器例子 - def my_decorator(func): - def wrapper(): - print("装饰器") - func() - return wrapper - - def greet(): - print("你好") - - greet = my_decorator(greet) - greet() - - # 原函数还是原函数吗? - print(greet.__name__) - print(help(greet)) - - # 使用functools.wrap - def my_decorator2(func): - @functools.wraps(func) - def wrapper(*args, **kwargs): - print("functools的装饰器") - func(*args, **kwargs) - return wrapper - - @my_decorator2 - def greet2(message): - print(message) - - greet2("functools") - print(greet2.__name__) - - # 类装饰器 - class Count(): - def __init__(self, func): - self.func = func - self.num_calls = 0 - - def __call__(self, *args, **kwargs): - self.num_calls += 1 - print("num of call is: {}".format(self.num_calls)) - return self.func(*args, **kwargs) - - @Count - def example(): - print("类装饰器") - - example() - example() - - # 装饰器嵌套 - def my_decorator_a(func): - @functools.wraps(func) - def wrapper(*args, **kwargs): - print("functools的装饰器a") - func(*args, **kwargs) - return wrapper - - def my_decorator_b(func): - @functools.wraps(func) - def wrapper(*args, **kwargs): - print("functools的装饰器b") - func(*args, **kwargs) - return wrapper - - @my_decorator_a - @my_decorator_b - def greet3(message): - print(message) - - greet3("functools") - print(greet3.__name__) - - # 应用举例 给函数加上计时功能 - def log_execution_time(func): - @functools.wraps(func) - def wrapper(*args, **kwargs): - start = time.perf_counter() - res = func(*args, **kwargs) - end = time.perf_counter() - print("函数{}运行耗时{}秒".format(func.__name__, end-start)) - return res - return wrapper - - @log_execution_time - def add(n): - s = 0 - for i in range(n): - s += i - return s - - res = add(10000) - print(res) - - @log_execution_time - def multiply(n): - s = 1 - for i in range(n): - s = s*(i+1) - return s - - res = multiply(10000) - print(res) - \ No newline at end of file + # 函数作为变量 + def func(message): + print("收到一个消息:{}".format(message)) + + + send_message = func + send_message("hello world") + + # 函数作为参数 + def root_call(fun, message): + print(fun(message)) + + + root_call(func, "函数参数") + + # 函数嵌套 + def fund(message): + def get_message(message): + print("收到一个消息:{}".format(message)) + + return get_message(message) + + + fund("函数嵌套") + + # 闭包 + # 闭包的三个条件: + # 1、必须有嵌套函数。 + # 2、内层函数必须引用外层函数的变量。 + # 3、外层函数必须返回内层函数本身,而不是返回内层函数的运行结果。 + def func_closure(): + def get_message(message): + print("收到一个消息:{}".format(message)) + + return get_message + + + send_message = func_closure() + print(send_message.__closure__) + send_message("返回函数对象(闭包)") + + + def func_closure(external_info): # 变量在外面 + def get_message(): + # 这里引用了外层的 external_info + print("收到外部环境的信息: {}".format(external_info)) + + return get_message + + + # 闭包在这一步已经“捕获”了 "我是被私藏的信息" + send = func_closure("我是被私藏的信息") + print(send.__closure__) + # 调用时不需要传参,它依然记得 "我是被私藏的信息" + send() + + # 简单装饰器例子 + def my_decorator(func): + def wrapper(): + print("装饰器") + func() + + return wrapper + + + def greet(): + print("你好") + + + greet = my_decorator(greet) + greet() + + # 原函数还是原函数吗? + print(greet.__name__) + print(help(greet)) + + # 使用functools.wrap + def my_decorator2(func): + # 如果没有 wraps:greet2.__name__ 会输出 "wrapper"。因为 greet2 已经被替换成了 wrapper 函数。这会破坏函数的元数据(如文档字符串、函数名等),导致调试困难。 + # 有了 wraps:它会自动把原函数 func(即 greet2)的属性复制到 wrapper 上。 + @functools.wraps(func) + def wrapper(*args, **kwargs): + print("functools的装饰器") + func(*args, **kwargs) + + return wrapper + + + @my_decorator2 + def greet2(message): + print(message) + + + greet2("functools") + print(greet2.__name__) + + # 类装饰器 + class Count(): + def __init__(self, func): + self.func = func + self.num_calls = 0 + + def __call__(self, *args, **kwargs): + self.num_calls += 1 + print("num of call is: {}".format(self.num_calls)) + return self.func(*args, **kwargs) + + + @Count + def example(): + print("类装饰器") + + + example() + example() + + # 装饰器嵌套 + def my_decorator_a(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + print("functools的装饰器a") + func(*args, **kwargs) + + return wrapper + + + def my_decorator_b(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + print("functools的装饰器b") + func(*args, **kwargs) + + return wrapper + + + @my_decorator_a + @my_decorator_b + def greet3(message): + print(message) + + + greet3("functools") + print(greet3.__name__) + + # 应用举例 给函数加上计时功能 + def log_execution_time(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + start = time.perf_counter() + res = func(*args, **kwargs) + end = time.perf_counter() + print("函数{}运行耗时{}秒".format(func.__name__, end - start)) + return res + + return wrapper + + + @log_execution_time + def add(n): + s = 0 + for i in range(n): + s += i + return s + + + res = add(10000) + print(res) + + + @log_execution_time + def multiply(n): + s = 1 + for i in range(n): + s = s * (i + 1) + return s + + + res = multiply(10000) + print(res) diff --git a/18/metaclass.py b/18/metaclass.py index db720284..09406dd8 100644 --- a/18/metaclass.py +++ b/18/metaclass.py @@ -6,70 +6,75 @@ class Monster(yaml.YAMLObject): - yaml_tag = "Monster" - def __init__(self, name, hp, ac, attacks): - self.name = name - self.hp = hp - self.ac = ac - self.attacks = attacks - - def __repr__(self): - return "{}(name = {}, hp = {}, ac = {}, attacks = {}".format(self.__class__.__name__, self.name, self.hp, self.ac, self.attacks) - + yaml_tag = "Monster" + + def __init__(self, name, hp, ac, attacks): + self.name = name + self.hp = hp + self.ac = ac + self.attacks = attacks + + def __repr__(self): + return "{}(name = {}, hp = {}, ac = {}, attacks = {}".format(self.__class__.__name__, self.name, self.hp, + self.ac, self.attacks) + if __name__ == "__main__": - Monster(name = "zym", hp = [2, 6], ac = 16, attacks = ["BITE", "HURT"]) - print(yaml.dump(Monster(name = "zym2", hp = [3, 6], ac = 18, attacks = ["BITE", "HURT"]))) - - # 所有用户自定义类,是type的实例 - class MyClass: - pass - - instance = MyClass() - print(type(instance)) - print(type(MyClass)) - # 用户自定义类,是type类的__call__运算符重载 - class MyClass2: - data = 1 - - instance = MyClass2() - print(MyClass2, instance, instance.data) - - MyClass = type("MyClass", (), {"data":1}) - instance = MyClass() - print(MyClass, instance, instance.data) - - # 网友的例子 - class MyMeta(type): - def __init__(self, name, bases, dic): - super().__init__(name, bases, dic) - print("===>MyMeta.__init__") - print(self.__name__) - print(dic) - print(self.yaml_tag) - - def __new__(cls, *args, **kwargs): - print("===>MyMeta.__new__") - print(cls.__name__) - return type.__new__(cls, *args, **kwargs) - - def __call__(cls, *args, **kwargs): - print("===>MyMeta.__call__") - obj = cls.__new__(cls) - cls.__init__(cls, *args, **kwargs) - return obj - - - class Foo(metaclass=MyMeta): - yaml_tag = "!Foo" - - def __init__(self, name): - print("Foo.__init__") - self.name = name - - def __new__(cls, *args, **kwargs): - print("Foo.__new__") - return object.__new__(cls) - - foo = Foo("foo") - \ No newline at end of file + Monster(name="zym", hp=[2, 6], ac=16, attacks=["BITE", "HURT"]) + print(yaml.dump(Monster(name="zym2", hp=[3, 6], ac=18, attacks=["BITE", "HURT"]))) + + # 所有用户自定义类,是type的实例 + class MyClass: + pass + + + instance = MyClass() + print(type(instance)) + print(type(MyClass)) + + # 用户自定义类,是type类的__call__运算符重载 + class MyClass2: + data = 1 + + + instance = MyClass2() + print(MyClass2, instance, instance.data) + + MyClass = type("MyClass", (), {"data": 1}) + instance = MyClass() + print(MyClass, instance, instance.data) + + # 网友的例子 + class MyMeta(type): + def __init__(self, name, bases, dic): + super().__init__(name, bases, dic) + print("===>MyMeta.__init__") + print(self.__name__) + print(dic) + print(self.yaml_tag) + + def __new__(cls, *args, **kwargs): + print("===>MyMeta.__new__") + print(cls.__name__) + return type.__new__(cls, *args, **kwargs) + + def __call__(cls, *args, **kwargs): + print("===>MyMeta.__call__") + obj = cls.__new__(cls) + cls.__init__(cls, *args, **kwargs) + return obj + + + class Foo(metaclass=MyMeta): + yaml_tag = "!Foo" + + def __init__(self, name): + print("Foo.__init__") + self.name = name + + def __new__(cls, *args, **kwargs): + print("Foo.__new__") + return object.__new__(cls) + + + foo = Foo("foo") diff --git a/19/diedai.py b/19/diedai.py index 8e93b0b4..5ac46747 100644 --- a/19/diedai.py +++ b/19/diedai.py @@ -7,129 +7,142 @@ import functools import time - if __name__ == "__main__": - # 判断一个对象是否可迭代 - def is_iterable(param): - try: - iter(param) - return True - except TypeError: - return False - - params = [ - 1234, - '1234', - [1, 2, 3, 4], - set([1, 2, 3, 4]), - {1:1, 2:2, 3:3, 4:4}, - (1, 2, 3, 4) - ] - for param in params: - print("{} is iterable? {}".format(param, is_iterable(param))) - - # 生成器 - def show_memory_info(hint): - pid = os.getpid() - p = psutil.Process(pid) - - info = p.memory_full_info() - memory = info.uss / 1024. /1024 - print("{} memory used: {}MB".format(hint, memory)) - - def log_execution_time(func): - @functools.wraps(func) - def wrapper(*args, **kwargs): - start = time.perf_counter() - res = func(*args, **kwargs) - end = time.perf_counter() - print("函数{}运行耗时{}秒".format(func.__name__, end-start)) - return res - return wrapper - - @log_execution_time - def test_iterator(): - show_memory_info("初始化迭代器") - list1 = [i for i in range(10000000)] - show_memory_info("初始化迭代器以后") - print(sum(list1)) - show_memory_info("调用sum以后") - - @log_execution_time - def test_generator(): - show_memory_info("初始化生成器") - list2 = (i for i in range(10000000)) - show_memory_info("初始化生成器以后") - print(sum(list2)) - show_memory_info("调用sum以后") - - test_iterator() - test_generator() - - # 使用生成器 - def generator(k): - i = 1 - while True: - yield i**k - i += 1 - - gen_1 = generator(1) - gen_3 = generator(3) - - def get_sum(n): - sum_1, sum_3 = 0, 0 - for i in range(n): - next_1 = next(gen_1) - next_3 = next(gen_3) - print("next_1={}, next_3={}".format(next_1, next_3)) - sum_1 += next_1 - sum_3 += next_3 - print(sum_1*sum_1, sum_3) - - get_sum(8) - - # 生成器的另一个例子,找指定元素在列表中的位置 - def index_generator(L, target): - for i, num in enumerate(L): - if num == target: - yield i - - print(list(index_generator([1, 6, 2, 4, 5, 2, 8, 6, 3, 2], 2))) - - # 给定两个有序序列,判断第一个是不是第二个的子序列 - def is_subsequence(a, b): - b = iter(b) - return all(i in b for i in a) - - print(is_subsequence([1,3,5], [1,2,3,4,5])) - print(is_subsequence([1,4,3], [1,2,3,4,5])) - - # 将上面的代码复杂化 - def is_subsequence2(a, b): - b = iter(b) - print(b) - - gen = (i for i in a) - print(gen) - - for i in gen: - print(i) - - gen = ((i in b) for i in a) - print(gen) - - for i in gen: - print(i) - - return all((i in b) for i in a) - - print(is_subsequence2([1,3,5], [1,2,3,4,5])) - print(is_subsequence2([1,4,3], [1,2,3,4,5])) - - # 思考题 有限元素生成器无限迭代 - gen = (i for i in range(5)) - for i in range(10): - print(next(gen)) - - - \ No newline at end of file + # 判断一个对象是否可迭代 + def is_iterable(param): + try: + iter(param) + return True + except TypeError: + return False + + + params = [ + 1234, + '1234', + [1, 2, 3, 4], + set([1, 2, 3, 4]), + {1: 1, 2: 2, 3: 3, 4: 4}, + (1, 2, 3, 4) + ] + for param in params: + print("{} is iterable? {}".format(param, is_iterable(param))) + + + # 生成器 + def show_memory_info(hint): + pid = os.getpid() + p = psutil.Process(pid) + + info = p.memory_full_info() + memory = info.uss / 1024. / 1024 + print("{} memory used: {}MB".format(hint, memory)) + + + def log_execution_time(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + start = time.perf_counter() + res = func(*args, **kwargs) + end = time.perf_counter() + print("函数{}运行耗时{}秒".format(func.__name__, end - start)) + return res + + return wrapper + + + @log_execution_time + def test_iterator(): + show_memory_info("初始化迭代器") + list1 = [i for i in range(10000000)] + show_memory_info("初始化迭代器以后") + print(sum(list1)) + show_memory_info("调用sum以后") + + + @log_execution_time + def test_generator(): + show_memory_info("初始化生成器") + list2 = (i for i in range(10000000)) + show_memory_info("初始化生成器以后") + print(sum(list2)) + show_memory_info("调用sum以后") + + + test_iterator() + test_generator() + + + # 使用生成器 + def generator(k): + i = 1 + while True: + yield i ** k + i += 1 + + + gen_1 = generator(1) + gen_3 = generator(3) + + + def get_sum(n): + sum_1, sum_3 = 0, 0 + for i in range(n): + next_1 = next(gen_1) + next_3 = next(gen_3) + print("next_1={}, next_3={}".format(next_1, next_3)) + sum_1 += next_1 + sum_3 += next_3 + print(sum_1 * sum_1, sum_3) + + + get_sum(8) + + + # 生成器的另一个例子,找指定元素在列表中的位置 + def index_generator(L, target): + for i, num in enumerate(L): + if num == target: + yield i + + + print(list(index_generator([1, 6, 2, 4, 5, 2, 8, 6, 3, 2], 2))) + + + # 给定两个有序序列,判断第一个是不是第二个的子序列 + def is_subsequence(a, b): + b = iter(b) + return all(i in b for i in a) + + + print(is_subsequence([1, 3, 5], [1, 2, 3, 4, 5])) + print(is_subsequence([1, 4, 3], [1, 2, 3, 4, 5])) + + + # 将上面的代码复杂化 + def is_subsequence2(a, b): + b = iter(b) + print(b) + + gen = (i for i in a) + print(gen) + + for i in gen: + print(i) + + gen = ((i in b) for i in a) + print(gen) + + for i in gen: + print(i) + + return all((i in b) for i in a) + + + print(is_subsequence2([1, 3, 5], [1, 2, 3, 4, 5])) + print(is_subsequence2([1, 4, 3], [1, 2, 3, 4, 5])) + + # 思考题 有限元素生成器无限迭代 + gen = (i for i in range(5)) + for i in range(10): + print(next(gen)) diff --git a/20/web_crawl.py b/20/web_crawl.py index 46ba946c..d60d0238 100644 --- a/20/web_crawl.py +++ b/20/web_crawl.py @@ -9,39 +9,39 @@ async def fetch_content(url): - async with aiohttp.ClientSession(connector = aiohttp.TCPConnector(ssl=False)) as session: - async with session.get(url) as response: - return await response.text() + async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False)) as session: + async with session.get(url) as response: + return await response.text() async def main(): - url = "https://movie.douban.com/cinema/later/beijing/" - init_page = await fetch_content(url) - init_soup = BeautifulSoup(init_page, 'lxml') - - movie_names, urls_to_fetch, movie_dates = [], [], [] - - all_movies = init_soup.find("div", id = "showing-soon") - - for each_movie in all_movies.find_all("div", class_ = "item"): - all_a_tag = each_movie.find_all('a') - all_li_tag = each_movie.find_all("li") - - movie_names.append(all_a_tag[1].text) - urls_to_fetch.append(all_a_tag[1]["href"]) - movie_dates.append(all_li_tag[0].text) - - tasks = [fetch_content(url) for url in urls_to_fetch] - pages = await asyncio.gather(*tasks) - - for movie_name, movie_date, page in zip(movie_names, movie_dates, pages): - soup_item = BeautifulSoup(page, "lxml") - img_tag = soup_item.find("img") - print("{} {} {}".format(movie_name, movie_date, img_tag["src"])) - + url = "https://movie.douban.com/cinema/later/beijing/" + init_page = await fetch_content(url) + init_soup = BeautifulSoup(init_page, 'lxml') + + movie_names, urls_to_fetch, movie_dates = [], [], [] + + all_movies = init_soup.find("div", id="showing-soon") + + for each_movie in all_movies.find_all("div", class_="item"): + all_a_tag = each_movie.find_all('a') + all_li_tag = each_movie.find_all("li") + + movie_names.append(all_a_tag[1].text) + urls_to_fetch.append(all_a_tag[1]["href"]) + movie_dates.append(all_li_tag[0].text) + + tasks = [fetch_content(url) for url in urls_to_fetch] + pages = await asyncio.gather(*tasks) + + for movie_name, movie_date, page in zip(movie_names, movie_dates, pages): + soup_item = BeautifulSoup(page, "lxml") + img_tag = soup_item.find("img") + print("{} {} {}".format(movie_name, movie_date, img_tag["src"])) + if __name__ == "__main__": - start = time.perf_counter() - asyncio.run(main()) - end = time.perf_counter() - print("协程爬虫运行耗时{}秒".format(end-start)) \ No newline at end of file + start = time.perf_counter() + asyncio.run(main()) + end = time.perf_counter() + print("协程爬虫运行耗时{}秒".format(end - start)) diff --git a/20/xc.py b/20/xc.py index 3d3d05d8..8f49e88f 100644 --- a/20/xc.py +++ b/20/xc.py @@ -9,173 +9,194 @@ def log_execution_time(func): - @functools.wraps(func) - def wrapper(*args, **kwargs): - start = time.perf_counter() - res = func(*args, **kwargs) - end = time.perf_counter() - print("函数{}运行耗时{}秒".format(func.__name__, end-start)) - return res - return wrapper + @functools.wraps(func) + def wrapper(*args, **kwargs): + start = time.perf_counter() + res = func(*args, **kwargs) + end = time.perf_counter() + print("函数{}运行耗时{}秒".format(func.__name__, end - start)) + return res + + return wrapper if __name__ == "__main__": - # 爬虫的例子 - def crawl_page(url): - print("正在爬取{}".format(url)) - sleep_time = int(url.split('_')[-1]) - time.sleep(sleep_time) - print("OK {}".format(url)) - - @log_execution_time - def main(urls): - for url in urls: - crawl_page(url) - - main(["url_1", "url_2", "url_3", "url_4"]) - - # 并发版爬虫,效果与上面一致 - async def crawl_page2(url): - print("正在爬取{}".format(url)) - sleep_time = int(url.split('_')[-1]) - await asyncio.sleep(sleep_time) - print("OK {}".format(url)) - - async def main2(urls): - for url in urls: - await crawl_page2(url) - - start = time.perf_counter() - asyncio.run(main2(["url_1", "url_2", "url_3", "url_4"])) - end = time.perf_counter() - print("2运行耗时{}秒".format(end-start)) - - # 真正的并发版爬虫 - async def crawl_page3(url): - print("正在爬取{}".format(url)) - sleep_time = int(url.split('_')[-1]) - await asyncio.sleep(sleep_time) - print("OK {}".format(url)) - - async def main3(urls): - tasks = [asyncio.create_task(crawl_page3(url)) for url in urls] - for task in tasks: - await task - - start = time.perf_counter() - asyncio.run(main3(["url_1", "url_2", "url_3", "url_4"])) - end = time.perf_counter() - print("3运行耗时{}秒".format(end-start)) - - # task的另一种做法 - async def main4(urls): - tasks = [asyncio.create_task(crawl_page3(url)) for url in urls] - await asyncio.gather(*tasks) - - start = time.perf_counter() - asyncio.run(main4(["url_1", "url_2", "url_3", "url_4"])) - end = time.perf_counter() - print("4运行耗时{}秒".format(end-start)) - - # 协程运行底层 - async def worker_1(): - print("work1开始") - await asyncio.sleep(1) - print("work1结束") - - async def worker_2(): - print("work2开始") - await asyncio.sleep(2) - print("work2结束") - - async def main5(): - print("await之前") - await worker_1() - print("await worker_1之后") - await worker_2() - print("await worker_2之后") - - start = time.perf_counter() - asyncio.run(main5()) - end = time.perf_counter() - print("5运行耗时{}秒".format(end-start)) - - async def main6(): - task1 = asyncio.create_task(worker_1()) - task2 = asyncio.create_task(worker_2()) - print("await之前") - await task1 - print("await worker_1之后") - await task2 - print("await worker_2之后") - - - start = time.perf_counter() - asyncio.run(main6()) - end = time.perf_counter() - print("6运行耗时{}秒".format(end-start)) - - # 限定时间,超出就取消。协程出现错误 - async def worker1(): - await asyncio.sleep(1) - return 1 - - async def worker2(): - await asyncio.sleep(2) - return 2/0 - - async def worker3(): - await asyncio.sleep(3) - return 3 - - async def main7(): - task1 = asyncio.create_task(worker1()) - task2 = asyncio.create_task(worker2()) - task3 = asyncio.create_task(worker3()) - await asyncio.sleep(2) - task3.cancel() - - res = await asyncio.gather(task2, task2, task3, return_exceptions=True) - print(res) - - start = time.perf_counter() - asyncio.run(main7()) - end = time.perf_counter() - print("7运行耗时{}秒".format(end-start)) - - # 生产者消费者模型 - async def consumer(queue, id): - while True: - val = await queue.get() - print("{} get a val:{}".format(id, val)) - await asyncio.sleep(1) - - async def producer(queue, id): - for i in range(5): - val = random.randint(1, 10) - await queue.put(val) - print("{} set a val:{}".format(id, val)) - await asyncio.sleep(1) - - async def main8(): - queue = asyncio.Queue() - - consumer_1 = asyncio.create_task(consumer(queue, "consumer_1")) - consumer_2 = asyncio.create_task(consumer(queue, "consumer_2")) - producer_1 = asyncio.create_task(producer(queue, "producer_1")) - producer_2 = asyncio.create_task(producer(queue, "producer_2")) - - await asyncio.sleep(10) - - consumer_1.cancel() - consumer_2.cancel() - - await asyncio.gather(consumer_1, consumer_2, producer_1, producer_2, return_exceptions = True) - - start = time.perf_counter() - asyncio.run(main8()) - end = time.perf_counter() - print("8运行耗时{}秒".format(end-start)) - - - \ No newline at end of file + # 爬虫的例子 + def crawl_page(url): + print("正在爬取{}".format(url)) + sleep_time = int(url.split('_')[-1]) + time.sleep(sleep_time) + print("OK {}".format(url)) + + + @log_execution_time + def main(urls): + for url in urls: + crawl_page(url) + + + main(["url_1", "url_2", "url_3", "url_4"]) + + + # 并发版爬虫,效果与上面一致 + async def crawl_page2(url): + print("正在爬取{}".format(url)) + sleep_time = int(url.split('_')[-1]) + await asyncio.sleep(sleep_time) + print("OK {}".format(url)) + + + async def main2(urls): + for url in urls: + await crawl_page2(url) + + + start = time.perf_counter() + asyncio.run(main2(["url_1", "url_2", "url_3", "url_4"])) + end = time.perf_counter() + print("2运行耗时{}秒".format(end - start)) + + + # 真正的并发版爬虫 + async def crawl_page3(url): + print("正在爬取{}".format(url)) + sleep_time = int(url.split('_')[-1]) + await asyncio.sleep(sleep_time) + print("OK {}".format(url)) + + + async def main3(urls): + tasks = [asyncio.create_task(crawl_page3(url)) for url in urls] + for task in tasks: + await task + + + start = time.perf_counter() + asyncio.run(main3(["url_1", "url_2", "url_3", "url_4"])) + end = time.perf_counter() + print("3运行耗时{}秒".format(end - start)) + + + # task的另一种做法 + async def main4(urls): + tasks = [asyncio.create_task(crawl_page3(url)) for url in urls] + await asyncio.gather(*tasks) + + + start = time.perf_counter() + asyncio.run(main4(["url_1", "url_2", "url_3", "url_4"])) + end = time.perf_counter() + print("4运行耗时{}秒".format(end - start)) + + + # 协程运行底层 + async def worker_1(): + print("work1开始") + await asyncio.sleep(1) + print("work1结束") + + + async def worker_2(): + print("work2开始") + await asyncio.sleep(2) + print("work2结束") + + + async def main5(): + print("await之前") + await worker_1() + print("await worker_1之后") + await worker_2() + print("await worker_2之后") + + + start = time.perf_counter() + asyncio.run(main5()) + end = time.perf_counter() + print("5运行耗时{}秒".format(end - start)) + + + async def main6(): + task1 = asyncio.create_task(worker_1()) + task2 = asyncio.create_task(worker_2()) + print("await之前") + await task1 + print("await worker_1之后") + await task2 + print("await worker_2之后") + + + start = time.perf_counter() + asyncio.run(main6()) + end = time.perf_counter() + print("6运行耗时{}秒".format(end - start)) + + # 限定时间,超出就取消。协程出现错误 + async def worker1(): + await asyncio.sleep(1) + return 1 + + + async def worker2(): + await asyncio.sleep(2) + return 2 / 0 + + + async def worker3(): + await asyncio.sleep(3) + return 3 + + + async def main7(): + task1 = asyncio.create_task(worker1()) + task2 = asyncio.create_task(worker2()) + task3 = asyncio.create_task(worker3()) + await asyncio.sleep(2) + task3.cancel() + + res = await asyncio.gather(task2, task2, task3, return_exceptions=True) + print(res) + + + start = time.perf_counter() + asyncio.run(main7()) + end = time.perf_counter() + print("7运行耗时{}秒".format(end - start)) + + + # 生产者消费者模型 + async def consumer(queue, id): + while True: + val = await queue.get() + print("{} get a val:{}".format(id, val)) + await asyncio.sleep(1) + + + async def producer(queue, id): + for i in range(5): + val = random.randint(1, 10) + await queue.put(val) + print("{} set a val:{}".format(id, val)) + await asyncio.sleep(1) + + + async def main8(): + queue = asyncio.Queue() + + consumer_1 = asyncio.create_task(consumer(queue, "consumer_1")) + consumer_2 = asyncio.create_task(consumer(queue, "consumer_2")) + producer_1 = asyncio.create_task(producer(queue, "producer_1")) + producer_2 = asyncio.create_task(producer(queue, "producer_2")) + + await asyncio.sleep(10) + + consumer_1.cancel() + consumer_2.cancel() + + await asyncio.gather(consumer_1, consumer_2, producer_1, producer_2, return_exceptions=True) + + + start = time.perf_counter() + asyncio.run(main8()) + end = time.perf_counter() + print("8运行耗时{}秒".format(end - start)) diff --git a/21/bf.py b/21/bf.py index b2da7147..74e40d10 100644 --- a/21/bf.py +++ b/21/bf.py @@ -27,7 +27,7 @@ def download_all_futures(sites): # 并行版 def download_all_futures_bx(sites): - with concurrent.futures.ThreadPoolExecutor() as executor: + with concurrent.futures.ProcessPoolExecutor() as executor: executor.map(download_one, sites) diff --git a/23/gil.py b/23/gil.py index 46867b6c..5a69275e 100644 --- a/23/gil.py +++ b/23/gil.py @@ -16,7 +16,8 @@ def CountDown(n): if __name__ == "__main__": - n = 3000000 + # n = 3000000 + n = 100000000 start_time = time.perf_counter() CountDown(n) end_time = time.perf_counter() diff --git "a/32-Python\346\240\270\345\277\203\346\212\200\346\234\257\344\270\216\345\256\236\346\210\230.epub" "b/32-Python\346\240\270\345\277\203\346\212\200\346\234\257\344\270\216\345\256\236\346\210\230.epub" new file mode 100644 index 00000000..78320366 Binary files /dev/null and "b/32-Python\346\240\270\345\277\203\346\212\200\346\234\257\344\270\216\345\256\236\346\210\230.epub" differ diff --git a/README.md b/README.md new file mode 100644 index 00000000..e9fad79f --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +极客时间课程《Python核心技术与实战》课程练习实践。 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..adaafbc9 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,15 @@ +[project] +name = "pythonpractice" +version = "0.1.0" +requires-python = ">=3.11" +dependencies = [ + "mypy>=1.20.2", + "objgraph>=3.6.2", + "psutil>=7.2.2", + "pydantic>=2.13.3", +] + +[[tool.uv.index]] +name = "aliyun" +url = "http://mirrors.aliyun.com/pypi/simple/" +default = true # 将其设为默认源 diff --git a/tkinter/helloworld.py b/tkinter/helloworld.py new file mode 100644 index 00000000..f2988a88 --- /dev/null +++ b/tkinter/helloworld.py @@ -0,0 +1,20 @@ +# 导入Tkinter模块,并用别名tk引用它。 +import tkinter as tk + + +# 定义一个函数say_hello,当按钮被点击时,这个函数会被调用。 这个函数会更新标签(label)的文本为"Hello World!"。 +def say_hello(): + label.config(text="Hello World!") + + +# 创建一个顶级窗口(root window),这是整个GUI程序的基础。 +root = tk.Tk() +# 创建一个标签(Label),设置其初始文本为"Click the button to say hello!",并将其添加到根窗口中。 +label = tk.Label(root, text="Click the button to say hello!") +label.pack() +# pack()方法用于将控件放置在父容器中,并自动调整它们的大小和位置。 +# 创建一个按钮(Button),设置其文本为"SAY Hello",并将其命令属性设置为say_hello函数。这意味着当用户点击此按钮时,say_hello函数将被调用。 +button = tk.Button(root, text="Say Hello", command=say_hello) +button.pack() +# 最后,进入主循环。在此过程中,程序会持续监听用户的操作,如点击按钮等,并作出相应的响应。 +root.mainloop() diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..aaf13fca --- /dev/null +++ b/uv.lock @@ -0,0 +1,351 @@ +version = 1 +revision = 3 +requires-python = ">=3.11" +resolution-markers = [ + "python_full_version >= '3.15'", + "python_full_version < '3.15'", +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "http://mirrors.aliyun.com/pypi/simple/" } +sdist = { url = "http://mirrors.aliyun.com/pypi/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89" } +wheels = [ + { url = "http://mirrors.aliyun.com/pypi/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53" }, +] + +[[package]] +name = "librt" +version = "0.10.0" +source = { registry = "http://mirrors.aliyun.com/pypi/simple/" } +sdist = { url = "http://mirrors.aliyun.com/pypi/packages/39/cb/c1945e506893b5b8577fb45a60c80e3ffe4a82092a04a6f29b0b951d9a24/librt-0.10.0.tar.gz", hash = "sha256:1aba1e8aa4e3307a7be68a74149545fde7451964dc0235a8bec5704a17bdda42" } +wheels = [ + { url = "http://mirrors.aliyun.com/pypi/packages/e2/a3/1472717d2325adacc8d335ba2e4078015c09d75b599f3cf48e967b3d306e/librt-0.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:01b4500ca3a625450c032a9142a8e843923ce263fa8a92ad1b38927cabe2fe72" }, + { url = "http://mirrors.aliyun.com/pypi/packages/a6/31/bfe32355d4b369aef3d7aa442df663bb5558c2ffa2de286cb2956346bc24/librt-0.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6b7e42d1b3e300d20bfc87e72ffd62f0a92a2cb3c35f7bf90df90c9d2a49f74c" }, + { url = "http://mirrors.aliyun.com/pypi/packages/e9/f1/83f8a2c715ba2cac9b7387a5a5cea25f717f7184320cfe48b36bed9c58e9/librt-0.10.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8ef7b8c61ce3a1b597cd3e15348ff1574325165c2e7ce09a718154cde2a7950" }, + { url = "http://mirrors.aliyun.com/pypi/packages/cc/94/c3a4ce94857f0004a542f86662806383611858f522722db58efaec0a1472/librt-0.10.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:e73c84f72d1fa0d6eaa7a1930b436ba8d2c90c58d77bfabb09995a69ad35f6c0" }, + { url = "http://mirrors.aliyun.com/pypi/packages/d1/41/e962bb26c7728eb7b3a69e490d0c800fd9968a6970e390c1f18ddb56093d/librt-0.10.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9728cb98713bd862fb8f4fd6a642d1896c86058a41d77c70f3d5cee75e725275" }, + { url = "http://mirrors.aliyun.com/pypi/packages/66/3a/4e46a707b1ecc993fd691071623b9beab89703a63bd21cc7807e06c28209/librt-0.10.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:648b7e941d20acd72f9652115e0e53facd98156d61f9ebf7a812bdef8bdccea9" }, + { url = "http://mirrors.aliyun.com/pypi/packages/b2/f5/dc5b7eb294656ad23d4ff4cf8514208d54fe1026b909d726a0dc026689c9/librt-0.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c3e33747c068e86a9007c20fdb777eb5ba8d3d19136d7812f88e69a713041b6f" }, + { url = "http://mirrors.aliyun.com/pypi/packages/58/e4/990ed8d12c7f114ac8f8ccd47f7d9bd9704ef61acfcb1df4a05047da7710/librt-0.10.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d509c745bf7e77d1107cf05e6abb249dc03fad13eb39f2286a49deedaeb2bcd7" }, + { url = "http://mirrors.aliyun.com/pypi/packages/60/eb/52d2726c7fb22818507dc3cc166c8f36dd4a4b68a7be67f12006ac8777c1/librt-0.10.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:786ad5a15e99d0e0e74f3adbeecc198a5ac58f340be07e984723d1e0074838de" }, + { url = "http://mirrors.aliyun.com/pypi/packages/bc/df/bd5591a78f7531fce4b6eb9962aadc6adc9560a01570442a884b6e554abe/librt-0.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:075582d877a97ee3d8e77bda3689dbe617b14f6469224a2d80b4b6c38e3951aa" }, + { url = "http://mirrors.aliyun.com/pypi/packages/fd/df/7c2b838dfc89a1762dd156d8b0c39848a7a2845d725a50be5a6e021fb8ba/librt-0.10.0-cp311-cp311-win32.whl", hash = "sha256:75ecdc3f5a90065aa2af2e574706c5495adc392520762dcf10b1aa716f0b8090" }, + { url = "http://mirrors.aliyun.com/pypi/packages/91/19/22ff572981049a9d436a083dbea1572d0f5dc068b7353637d2dd9977c8f1/librt-0.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:b6f6084884131d8a52cb9d7095ff2aa52c1e786d9fdaefab1fb4515415e9e083" }, + { url = "http://mirrors.aliyun.com/pypi/packages/12/22/1697cc64f4a5c7e9bce55e99c6d234a346beaedaefcd1e2ca90dd285f98c/librt-0.10.0-cp311-cp311-win_arm64.whl", hash = "sha256:0140bd62151160047e89b2730cb6f8506cdac5127baa1afb9231e4dd3fe7f681" }, + { url = "http://mirrors.aliyun.com/pypi/packages/12/8e/cbb5b6f6e45e65c10a42449a69eaccc44d73e6a081ea752fbc5221c6dc1c/librt-0.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b4b58a44b407e91f633dafee008de9ddea6aa2a555ed94929c099260910bd0ba" }, + { url = "http://mirrors.aliyun.com/pypi/packages/e9/3d/8233cbee8e99e6a8992f02bfc2dec8d787509566a511d1fde2574ee7473f/librt-0.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:950b79b11762531bdf45a9df909d2f9a2a8445c70c88665c01d14c8511a27dc5" }, + { url = "http://mirrors.aliyun.com/pypi/packages/87/6f/5264b298cef2b72fc97d2dde56c66181eda35204bf5dcd1ed0c3d0a0a782/librt-0.10.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4538453f51be197633b425912c150e25b0667252d3741c53e8368176d98d9d37" }, + { url = "http://mirrors.aliyun.com/pypi/packages/07/7b/19b1b859cc60d5f99276cc2b3144d91556c6d1b1e4ebb50359696bebf7a8/librt-0.10.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:70b955f091beac93e994a0b7ec616934f63b3ea5c3d6d7af847562f935aceca7" }, + { url = "http://mirrors.aliyun.com/pypi/packages/6e/56/a2f40717142a8af46289f57874ef914353d8faccd5e4f8e594ab1e16e8c7/librt-0.10.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:483e685e06b6163728ba6c85d74315176be7190f432ec2a41226e5e14355d5f0" }, + { url = "http://mirrors.aliyun.com/pypi/packages/67/ca/15c625c3bdc0167c01e04ef8878317e9713f3bfa788438342f7a94c7b22c/librt-0.10.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7ac53d946a009d1a38c44a60812708c9458fb2a239a5f630d8e625571386650f" }, + { url = "http://mirrors.aliyun.com/pypi/packages/ed/c5/ba301d571d9e05844e2435b73aba30bee77bb75ce155c9affcfd2173dd03/librt-0.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bc8771c9fcf0ea894ca41fdc2abd83572c2fbda221f232d86e718614e57ff513" }, + { url = "http://mirrors.aliyun.com/pypi/packages/8b/60/af70e135bc1f1fe15dd3894b1e4bbefc7ecdf911749a925a39eb86ceb2a1/librt-0.10.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:70805dbc5257892ac572f86290a61e3c8d90224ecce1a8b2d1f7ed51965417f4" }, + { url = "http://mirrors.aliyun.com/pypi/packages/83/c2/c8236eb8b421bac5a172ba208f965abaa89805da2a3fa112bdf1764caf8f/librt-0.10.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d3b4f300f7bcba6e2ff73fb8bef1898479e9772bfa2682998c636391633ec826" }, + { url = "http://mirrors.aliyun.com/pypi/packages/d6/f5/15b6d32bc25dacd4a60886a683d8128d6219910c122202b995a40dd4f8d2/librt-0.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:943bc943f92f4fb3408fae62485c6a3ad68ce4f2ee205643a39641525c19a276" }, + { url = "http://mirrors.aliyun.com/pypi/packages/fb/8e/b1b959bacd323eb4360579db992513e1406d1c6ef7edb57b5511fd0666fd/librt-0.10.0-cp312-cp312-win32.whl", hash = "sha256:6065c1a758fba1010b41401013903d3d5d2750eab425ddedd584abac31d0630e" }, + { url = "http://mirrors.aliyun.com/pypi/packages/9e/4c/d4cd6e4b9fc24098e63cc85537d1b6689682aee96809c38f08072067cc2b/librt-0.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:d788ecbe208ab352dab0e105cc06057bf9a2fc7e58cabb0d751ad9e30062b9e2" }, + { url = "http://mirrors.aliyun.com/pypi/packages/2b/19/8641da1f63d24b92354a492f893c022d6b3a0df44e70c8eff49364613983/librt-0.10.0-cp312-cp312-win_arm64.whl", hash = "sha256:6003d1f295bdba02656dc81308208fc060d0a51d8c0d0a6db70f7f3c57b9ba0a" }, + { url = "http://mirrors.aliyun.com/pypi/packages/e5/29/681a75c82f4cc90d29e4b257a3299b79fe13fe927a04c57b8109d70b6957/librt-0.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f0ede79d682e73f91c1b599a76d78b7464b9b5d213754cedb13372d9df36e596" }, + { url = "http://mirrors.aliyun.com/pypi/packages/62/24/0c7ca445a55d04be79cac19819437fd094782347fa116f6681844fa6143e/librt-0.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e0ba0b131fdb336c8b9c948e397f4a7e649d0f783b529f07b647bf4961df392e" }, + { url = "http://mirrors.aliyun.com/pypi/packages/fe/1f/1e2b8f6443ef9e9a81e89486ca70e22f3684f93db003ce6eaefc3d0839b9/librt-0.10.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2728117da2afb96fb957768725ee43dc9a2d73b031e02da424b818a3cdd3a275" }, + { url = "http://mirrors.aliyun.com/pypi/packages/74/61/9dc9e03de0439ad84c1c240aac8b747f12c90cb797ea6042f7bdb8d3410f/librt-0.10.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:723ba80594c49cdf0584196fc430752262605dc9449902fc9bd3d9b79976cb77" }, + { url = "http://mirrors.aliyun.com/pypi/packages/55/f4/635223117d7590875bca441275065a3bf491203ad4208bd1cc3ffd90c5a1/librt-0.10.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7292edaaca294a61a978c53a3c7d6130d099b0dfbc8f0a65916cdc6b891b9852" }, + { url = "http://mirrors.aliyun.com/pypi/packages/e5/66/b04152d0cd8b6ca2b428a8bd3230343230c35ed304a932f35b5375f2f828/librt-0.10.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:89fe9d539f2c10a1666633eeeac507ce95dd06d9ecc58de3c6390dba156a3d3a" }, + { url = "http://mirrors.aliyun.com/pypi/packages/35/1e/25bac4c7f2ca36f0e612cade186970683cf79153d96beccc3a11a9e19b97/librt-0.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4efa7b9587503fa5b67f40593302b9c8836d211d222ff9f7cafe67be5f8f0b10" }, + { url = "http://mirrors.aliyun.com/pypi/packages/18/54/4601faab35b6632a13200faa146ca62bfd111ffbe2568be430d65c89493a/librt-0.10.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:22dc982ef59df0136df36092ccbdbb570ced8aafb33e49585739b2f1de1c13b6" }, + { url = "http://mirrors.aliyun.com/pypi/packages/1b/cf/39f4023509e94fade8b074666fa3292db9cb6b34ea5dcbe7af53df9fca1d/librt-0.10.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:6f2e5f3606253a84cea719c94a3bb1c54487b5d617d0254d46e0920d8a06be3f" }, + { url = "http://mirrors.aliyun.com/pypi/packages/8e/00/40247209fc46a8e308a91412d5206aedf8efb667ee89eb625820106a5c2f/librt-0.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:40884bfaa1e29f6b6a9be255007d8f359bfc9e61d68bdef8ed3158bfcbc95df9" }, + { url = "http://mirrors.aliyun.com/pypi/packages/d8/6e/5566beb94431a985abe1787af5ef86e087750172ff9d0bbf20f93e88132d/librt-0.10.0-cp313-cp313-win32.whl", hash = "sha256:3cd34cd8254eba756660bff6c2da91278248184301054fe3e4feb073bdd49b14" }, + { url = "http://mirrors.aliyun.com/pypi/packages/d0/c2/3ea3301d6c8dff51d39dbe8ed75db3dc92896947d4afb5eeadf821c1e67f/librt-0.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:7baac5313e2d8dce1386f97777a8d03ab28f5fe1e780b3b9ac2ee7544551fedc" }, + { url = "http://mirrors.aliyun.com/pypi/packages/3c/de/5d49cb92cadcbc77d3abc27b93fd6030ed8437487dde2eae38cab5e6704d/librt-0.10.0-cp313-cp313-win_arm64.whl", hash = "sha256:afc5b4406c8e2515698d922a5c7823a009312835ea58196671fff40e35cb8166" }, + { url = "http://mirrors.aliyun.com/pypi/packages/6a/64/7165e08108cc185a13a9c069f0685e6ef92e70e07fddf7edf5e7348c6316/librt-0.10.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:f09588a30e6a22ec624090d72a3ab1a6d4d5485c3ed739603e76aa3c16efa688" }, + { url = "http://mirrors.aliyun.com/pypi/packages/ae/ef/bf8613febf651b90c5222ee79dea5ae58d4cc2b544df69d3033424448934/librt-0.10.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:131ade118d12bd7a0adc4e655474a553f1b76cf78385868885944d21d51e45e0" }, + { url = "http://mirrors.aliyun.com/pypi/packages/b6/67/9eddd165c1d8397bdf99b38bf12b5a55b3def5035b49eedb49f2775d1430/librt-0.10.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8b9ab28e40d011c373a189eae900c916e66d6fbecf7983e9e4883089ee085ef" }, + { url = "http://mirrors.aliyun.com/pypi/packages/10/d1/d95da80334501866cd37004ab5d7483220d05862fab4b5405394f0264f0d/librt-0.10.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:67c39bb30da73bae1f293d1ed8bc2f8f6642649dd0928d3600aeff3041ac23d6" }, + { url = "http://mirrors.aliyun.com/pypi/packages/0c/fa/e6d64d28718bc1be4e1736fcb037ca1c4dfca927e7167df75a7d5215665e/librt-0.10.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8c3273c6b774614f093c8927c2bf1b077d0fefde988fe98f46a333734e5597ab" }, + { url = "http://mirrors.aliyun.com/pypi/packages/72/3f/3fdb77e7f937dad59cfd76b720be7e7643400ec76b2da35befab8d66ba30/librt-0.10.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9dd7c1b86a4baa583ab5db977484b93a2c474e69e96ef3e9538387ea54229cb9" }, + { url = "http://mirrors.aliyun.com/pypi/packages/18/ca/f4d49133dd86a6f55d79eca30bf412fa722f511a9abe67f62f57aa64e66a/librt-0.10.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a77385c5a202e831149f7ad03be9e67cf80e957e52c614e83dcb822c95222eb8" }, + { url = "http://mirrors.aliyun.com/pypi/packages/de/66/a8df2fbadc1f6c1827a096d11c40175bd526133480bd3bc88ec64a03d257/librt-0.10.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:c6a5eafa74b5655bad59886138ed68426f098a6beb8cb95a71f2cc3cd8bb33fe" }, + { url = "http://mirrors.aliyun.com/pypi/packages/bb/73/1e3c83613fe05451bb969e27b68a573d177f08d5f63533cc29fec0989658/librt-0.10.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:1fc93d0439204c50ab4d1512611ce2c206f1b369b419f69c7c27c761561e3291" }, + { url = "http://mirrors.aliyun.com/pypi/packages/09/24/5e2f926ee9d3ef348d9339526d7062abb5c44d8419e3179528c01d78c102/librt-0.10.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:79e713c178bc7a744adfbee6b4619a288eecc0c914da2a9313a20255abe2f0cf" }, + { url = "http://mirrors.aliyun.com/pypi/packages/fc/7d/3e89ed6ad0162561fa8bef9df3195e24263104c955713cd0237d3711fad2/librt-0.10.0-cp314-cp314-win32.whl", hash = "sha256:2eba9d955a68c41d9f326be3da42f163ec3518b7ab20f1c826224e7bed71e0bf" }, + { url = "http://mirrors.aliyun.com/pypi/packages/76/25/579e731c94a7086a268bfa3e7a4945cd47836bebd3cbf3faeafd2e7eaef9/librt-0.10.0-cp314-cp314-win_amd64.whl", hash = "sha256:cbfaf7f5145e9917f5d18bffa298eff6a19d74e7b8b11dabdca95785befe8dbf" }, + { url = "http://mirrors.aliyun.com/pypi/packages/6e/f8/235822b7ae0b2334f12ee18bcf2476d07924077a5efeea57dbe927704be2/librt-0.10.0-cp314-cp314-win_arm64.whl", hash = "sha256:8d6d385d1969849a6b1397114df22714b6ded917bada98668e3e974dc663477e" }, + { url = "http://mirrors.aliyun.com/pypi/packages/9f/e3/9b919cbf1e8eb770bf91bb7df28125e0f1daf4587169afefd95402636e9a/librt-0.10.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:6c3a82d3bd32631ef5c79922dfc028520c9ad840255979ab4d908271818039ee" }, + { url = "http://mirrors.aliyun.com/pypi/packages/6a/f5/72a944aa3bc3498169a168087eff58ca48b58bf1b704e59d091fd30739f3/librt-0.10.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d64cc66005dc324c9bb1fa3fc2841f529002f6eb15966d55e46d430f56955a6a" }, + { url = "http://mirrors.aliyun.com/pypi/packages/9c/e3/fcc290a33e295019759472dfa794d204e43504b276ac65eab7fd9da20ea3/librt-0.10.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9bb562cd28c88cd2c6a9a6c78f99dc39348d6b16c94adc25de0e574acf1176e9" }, + { url = "http://mirrors.aliyun.com/pypi/packages/fd/54/546975e4c997573885e7f040a05012f8838e06fb12b0c3c1fbb76254e9d7/librt-0.10.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:b809aa2854d019c28773b03605df22adc675ee4f3f4402d673581313e8906119" }, + { url = "http://mirrors.aliyun.com/pypi/packages/70/8c/f1d03401571b331653acddbd4e8cd955c06d945241dd08b25192fac0d04b/librt-0.10.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cc15acabdd519bd4176fdadc2119e5e3093485d86f89138daf47e5b4cedb983a" }, + { url = "http://mirrors.aliyun.com/pypi/packages/0c/08/62cf80ff046c339faf56718b3a940244d4beb70f1c6407289b5830ec11e9/librt-0.10.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b1b2d835307d08ddadd94568e2369648ec9173bd3eea6d7f52a1abe717c81f98" }, + { url = "http://mirrors.aliyun.com/pypi/packages/d9/ea/da5918d4070362e9a4d2ee9cd34f9dc84902daad8fd4275f8504a727ff4e/librt-0.10.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d261c6a2f93335a5167887fb0223e8b98ffce20ee3fde242e8e58a37ece6d0e5" }, + { url = "http://mirrors.aliyun.com/pypi/packages/c9/8d/68b6086bed1fcdc314c640ea04e31e52d18052e08059fa595409d66a51a9/librt-0.10.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e2ffd44963f8e7f68995504d90f9881d64e94dc1d8e310039b9526108fc0c0f7" }, + { url = "http://mirrors.aliyun.com/pypi/packages/06/c8/b810f1d84ec34a5a7ed93d7b510ab04164d75fbdf23088d5c3fbe6b08357/librt-0.10.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:5f285f6455ed495791c4d8630e5af732960adea93cac4c893d15619f2eae53e8" }, + { url = "http://mirrors.aliyun.com/pypi/packages/5a/00/3c82d4158c5a2c62528b8fccce65a8c9ad700e480e86f9389387435089a5/librt-0.10.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f6034ff52e663d34c7b82ef2aa2f94ad7c1d939e2368e63b06844bc4d127d2e1" }, + { url = "http://mirrors.aliyun.com/pypi/packages/99/3a/9c635ac3e8a00383ff689161d3eac8a30b3b2ddc711b40471e6b8983ea29/librt-0.10.0-cp314-cp314t-win32.whl", hash = "sha256:657860fd877fba6a241ea088ef99f63ca819945d3c715265da670bad56c37ebe" }, + { url = "http://mirrors.aliyun.com/pypi/packages/dc/e8/6f65f3e565d4ac212cddddd552eacc8035ffdf941ca0ad6fe945a211d41f/librt-0.10.0-cp314-cp314t-win_amd64.whl", hash = "sha256:56ded2d66010203a0cb5af063b609e3f079531a0e5e576d618dece859fd2e1af" }, + { url = "http://mirrors.aliyun.com/pypi/packages/51/78/a0705a67cacd81e5fa01a5035b3adbdfbb43a7b8d4bd27e2b282ae61baf2/librt-0.10.0-cp314-cp314t-win_arm64.whl", hash = "sha256:1ee63f30abf18ed4830fdbaf87b2b6f4bba1e198d46085c314edde4045e56715" }, +] + +[[package]] +name = "mypy" +version = "1.20.2" +source = { registry = "http://mirrors.aliyun.com/pypi/simple/" } +dependencies = [ + { name = "librt", marker = "platform_python_implementation != 'PyPy'" }, + { name = "mypy-extensions" }, + { name = "pathspec" }, + { name = "typing-extensions" }, +] +sdist = { url = "http://mirrors.aliyun.com/pypi/packages/04/af/e3d4b3e9ec91a0ff9aabfdb38692952acf49bbb899c2e4c29acb3a6da3ae/mypy-1.20.2.tar.gz", hash = "sha256:e8222c26daaafd9e8626dec58ae36029f82585890589576f769a650dd20fd665" } +wheels = [ + { url = "http://mirrors.aliyun.com/pypi/packages/1f/4d/9ebeae211caccbdaddde7ed5e31dfcf57faac66be9b11deb1dc6526c8078/mypy-1.20.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4077797a273e56e8843d001e9dfe4ba10e33323d6ade647ff260e5cd97d9758c" }, + { url = "http://mirrors.aliyun.com/pypi/packages/95/d7/93473d34b61f04fac1aecc01368485c89c5c4af7a4b9a0cab5d77d04b63f/mypy-1.20.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cdecf62abcc4292500d7858aeae87a1f8f1150f4c4dd08fb0b336ee79b2a6df3" }, + { url = "http://mirrors.aliyun.com/pypi/packages/e2/30/3dd903e8bafb7b5f7bf87fcd58f8382086dea2aa19f0a7b357f21f63071b/mypy-1.20.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c566c3a88b6ece59b3d70f65bedef17304f48eb52ff040a6a18214e1917b3254" }, + { url = "http://mirrors.aliyun.com/pypi/packages/07/05/c61a140aba4c729ac7bc99ae26fc627c78a6e08f5b9dd319244ea71a3d7e/mypy-1.20.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0deb80d062b2479f2c87ae568f89845afc71d11bc41b04179e58165fd9f31e98" }, + { url = "http://mirrors.aliyun.com/pypi/packages/fd/87/da78243742ffa8a36d98c3010f0d829f93d5da4e6786f1a1a6f2ad616502/mypy-1.20.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bba9ad231e92a3e424b3e56b65aa17704993425bba97e302c832f9466bb85bac" }, + { url = "http://mirrors.aliyun.com/pypi/packages/37/52/10a1ddf91b40f843943a3c6db51e2df59c9e237f29d355e95eaab427461f/mypy-1.20.2-cp311-cp311-win_amd64.whl", hash = "sha256:baf593f2765fa3a6b1ef95807dbaa3d25b594f6a52adcc506a6b9cb115e1be67" }, + { url = "http://mirrors.aliyun.com/pypi/packages/20/02/f9a4415b664c53bd34d6709be59da303abcae986dc4ac847b402edb6fa1e/mypy-1.20.2-cp311-cp311-win_arm64.whl", hash = "sha256:20175a1c0f49863946ec20b7f63255768058ac4f07d2b9ded6a6b46cfb5a9100" }, + { url = "http://mirrors.aliyun.com/pypi/packages/71/4e/7560e4528db9e9b147e4c0f22660466bf30a0a1fe3d63d1b9d3b0fd354ee/mypy-1.20.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4dbfcf869f6b0517f70cf0030ba6ea1d6645e132337a7d5204a18d8d5636c02b" }, + { url = "http://mirrors.aliyun.com/pypi/packages/32/d9/34a5efed8124f5a9234f55ac6a4ced4201e2c5b81e1109c49ad23190ec8c/mypy-1.20.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4b6481b228d072315b053210b01ac320e1be243dc17f9e5887ef167f23f5fae4" }, + { url = "http://mirrors.aliyun.com/pypi/packages/d1/14/eb377acf78c03c92d566a1510cda8137348215b5335085ef662ab82ecd3a/mypy-1.20.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:34397cdced6b90b836e38182076049fdb41424322e0b0728c946b0939ebdf9f6" }, + { url = "http://mirrors.aliyun.com/pypi/packages/b9/94/7e4634a32b641aa1c112422eed1bbece61ee16205f674190e8b536f884de/mypy-1.20.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a5da6976f20cae27059ea8d0c86e7cef3de720e04c4bb9ee18e3690fdb792066" }, + { url = "http://mirrors.aliyun.com/pypi/packages/7a/f3/f7e62395cb7f434541b4491a01149a4439e28ace4c0c632bbf5431e92d1f/mypy-1.20.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:56908d7e08318d39f85b1f0c6cfd47b0cac1a130da677630dac0de3e0623e102" }, + { url = "http://mirrors.aliyun.com/pypi/packages/3e/0d/47e3c3a0ec2a876e35aeac365df3cac7776c36bbd4ed18cc521e1b9d255b/mypy-1.20.2-cp312-cp312-win_amd64.whl", hash = "sha256:d52ad8d78522da1d308789df651ee5379088e77c76cb1994858d40a426b343b9" }, + { url = "http://mirrors.aliyun.com/pypi/packages/d6/b2/6c852d72e0ea8b01f49da817fb52539993cde327e7d010e0103dc12d0dac/mypy-1.20.2-cp312-cp312-win_arm64.whl", hash = "sha256:785b08db19c9f214dc37d65f7c165d19a30fcecb48abfa30f31b01b5acaabb58" }, + { url = "http://mirrors.aliyun.com/pypi/packages/5b/c4/b93812d3a192c9bcf5df405bd2f30277cd0e48106a14d1023c7f6ed6e39b/mypy-1.20.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:edfbfca868cdd6bd8d974a60f8a3682f5565d3f5c99b327640cedd24c4264026" }, + { url = "http://mirrors.aliyun.com/pypi/packages/f3/47/42c122501bff18eaf1e8f457f5c017933452d8acdc52918a9f59f6812955/mypy-1.20.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e2877a02380adfcdbc69071a0f74d6e9dbbf593c0dc9d174e1f223ffd5281943" }, + { url = "http://mirrors.aliyun.com/pypi/packages/92/8f/75bbc92f41725fbd585fb17b440b1119b576105df1013622983e18640a93/mypy-1.20.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7488448de6007cd5177c6cea0517ac33b4c0f5ee9b5e9f2be51ce75511a85517" }, + { url = "http://mirrors.aliyun.com/pypi/packages/a1/32/4c49da27a606167391ff0c39aa955707a00edc500572e562f7c36c08a71f/mypy-1.20.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bb9c2fa06887e21d6a3a868762acb82aec34e2c6fd0174064f27c93ede68ad15" }, + { url = "http://mirrors.aliyun.com/pypi/packages/7f/fc/4e354a1bd70216359deb0c9c54847ee6b32ef78dfb09f5131ff99b494078/mypy-1.20.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9d56a78b646f2e3daa865bc70cd5ec5a46c50045801ca8ff17a0c43abc97e3ee" }, + { url = "http://mirrors.aliyun.com/pypi/packages/62/b2/c0f2056e9eb8f08c62cafd9715e4584b89132bdc832fcf85d27d07b5f3e5/mypy-1.20.2-cp313-cp313-win_amd64.whl", hash = "sha256:2a4102b03bb7481d9a91a6da8d174740c9c8c4401024684b9ca3b7cc5e49852f" }, + { url = "http://mirrors.aliyun.com/pypi/packages/e5/14/065e333721f05de8ef683d0aa804c23026bcc287446b61cac657b902ccac/mypy-1.20.2-cp313-cp313-win_arm64.whl", hash = "sha256:a95a9248b0c6fd933a442c03c3b113c3b61320086b88e2c444676d3fd1ca3330" }, + { url = "http://mirrors.aliyun.com/pypi/packages/ae/d1/b4ec96b0ecc620a4443570c6e95c867903428cfcde4206518eafdd5880c3/mypy-1.20.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:419413398fe250aae057fd2fe50166b61077083c9b82754c341cf4fd73038f30" }, + { url = "http://mirrors.aliyun.com/pypi/packages/3a/63/d2c2ff4fa66bc49477d32dfa26e8a167ba803ea6a69c5efb416036909d30/mypy-1.20.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e73c07f23009962885c197ccb9b41356a30cc0e5a1d0c2ea8fd8fb1362d7f924" }, + { url = "http://mirrors.aliyun.com/pypi/packages/2a/56/983916806bf4eddeaaa2c9230903c3669c6718552a921154e1c5182c701f/mypy-1.20.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c64e5973df366b747646fc98da921f9d6eba9716d57d1db94a83c026a08e0fb" }, + { url = "http://mirrors.aliyun.com/pypi/packages/19/65/0cd9285ab010ee8214c83d67c6b49417c40d86ce46f1aa109457b5a9b8d7/mypy-1.20.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a65aa591af023864fd08a97da9974e919452cfe19cb146c8a5dc692626445dc" }, + { url = "http://mirrors.aliyun.com/pypi/packages/94/97/48ff3b297cafcc94d185243a9190836fb1b01c1b0918fff64e941e973cc9/mypy-1.20.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4fef51b01e638974a6e69885687e9bd40c8d1e09a6cd291cca0619625cf1f558" }, + { url = "http://mirrors.aliyun.com/pypi/packages/fd/a1/1b4233d255bdd0b38a1f284feeb1c143ca508c19184964e22f8d837ec851/mypy-1.20.2-cp314-cp314-win_amd64.whl", hash = "sha256:913485a03f1bcf5d279409a9d2b9ed565c151f61c09f29991e5faa14033da4c8" }, + { url = "http://mirrors.aliyun.com/pypi/packages/78/c2/ce7ee2ba36aeb954ba50f18fa25d9c1188578654b97d02a66a15b6f09531/mypy-1.20.2-cp314-cp314-win_arm64.whl", hash = "sha256:c3bae4f855d965b5453784300c12ffc63a548304ac7f99e55d4dc7c898673aa3" }, + { url = "http://mirrors.aliyun.com/pypi/packages/4e/a1/9d93a7d0b5859af0ead82b4888b46df6c8797e1bc5e1e262a08518c6d48e/mypy-1.20.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2de3dcea53babc1c3237a19002bc3d228ce1833278f093b8d619e06e7cc79609" }, + { url = "http://mirrors.aliyun.com/pypi/packages/00/d2/09a6a10ee1bf0008f6c144d9676f2ca6a12512151b4e0ad0ff6c4fac5337/mypy-1.20.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:52b176444e2e5054dfcbcb8c75b0b719865c96247b37407184bbfca5c353f2c2" }, + { url = "http://mirrors.aliyun.com/pypi/packages/57/da/9594b75c3c019e805250bed3583bdf4443ff9e6ef08f97e39ae308cb06f2/mypy-1.20.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:688c3312e5dadb573a2c69c82af3a298d43ecf9e6d264e0f95df960b5f6ac19c" }, + { url = "http://mirrors.aliyun.com/pypi/packages/97/77/f75a65c278e6e8eba2071f7f5a90481891053ecc39878cc444634d892abe/mypy-1.20.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29752dbbf8cc53f89f6ac096d363314333045c257c9c75cbd189ca2de0455744" }, + { url = "http://mirrors.aliyun.com/pypi/packages/d7/46/1a4e1c66e96c1a3246ddf5403d122ac9b0a8d2b7e65730b9d6533ba7a6d3/mypy-1.20.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:803203d2b6ea644982c644895c2f78b28d0e208bba7b27d9b921e0ec5eb207c6" }, + { url = "http://mirrors.aliyun.com/pypi/packages/5a/2c/78a8851264dec38cd736ca5b8bc9380674df0dd0be7792f538916157716c/mypy-1.20.2-cp314-cp314t-win_amd64.whl", hash = "sha256:9bcb8aa397ff0093c824182fd76a935a9ba7ad097fcbef80ae89bf6c1731d8ec" }, + { url = "http://mirrors.aliyun.com/pypi/packages/83/01/cd7318aa03493322ce275a0e14f4f52b8896335e4e79d4fb8153a7ad2b77/mypy-1.20.2-cp314-cp314t-win_arm64.whl", hash = "sha256:e061b58443f1736f8a37c48978d7ab581636d6ab03e3d4f99e3fa90463bb9382" }, + { url = "http://mirrors.aliyun.com/pypi/packages/28/9a/f23c163e25b11074188251b0b5a0342625fc1cdb6af604757174fa9acc9b/mypy-1.20.2-py3-none-any.whl", hash = "sha256:a94c5a76ab46c5e6257c7972b6c8cff0574201ca7dc05647e33e795d78680563" }, +] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +source = { registry = "http://mirrors.aliyun.com/pypi/simple/" } +sdist = { url = "http://mirrors.aliyun.com/pypi/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558" } +wheels = [ + { url = "http://mirrors.aliyun.com/pypi/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505" }, +] + +[[package]] +name = "objgraph" +version = "3.6.2" +source = { registry = "http://mirrors.aliyun.com/pypi/simple/" } +sdist = { url = "http://mirrors.aliyun.com/pypi/packages/ba/74/60dfb345ca493d69551dd1ba599ceb6fe325527fedabe4217d6e030449e2/objgraph-3.6.2.tar.gz", hash = "sha256:00b9f2f40f7422e3c7f45a61c4dafdaf81f03ff0649d6eaec866f01030e51ad8" } +wheels = [ + { url = "http://mirrors.aliyun.com/pypi/packages/8e/67/7bffbb861cb8a0a62b7df50738d35812bf40dc8bcc1559c04bdf593f1164/objgraph-3.6.2-py3-none-any.whl", hash = "sha256:8114c97712291c3ba30d882406a384d0a7651b307ea9a06e0d83836ccde85e15" }, +] + +[[package]] +name = "pathspec" +version = "1.1.1" +source = { registry = "http://mirrors.aliyun.com/pypi/simple/" } +sdist = { url = "http://mirrors.aliyun.com/pypi/packages/5a/82/42f767fc1c1143d6fd36efb827202a2d997a375e160a71eb2888a925aac1/pathspec-1.1.1.tar.gz", hash = "sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a" } +wheels = [ + { url = "http://mirrors.aliyun.com/pypi/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl", hash = "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189" }, +] + +[[package]] +name = "psutil" +version = "7.2.2" +source = { registry = "http://mirrors.aliyun.com/pypi/simple/" } +sdist = { url = "http://mirrors.aliyun.com/pypi/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372" } +wheels = [ + { url = "http://mirrors.aliyun.com/pypi/packages/51/08/510cbdb69c25a96f4ae523f733cdc963ae654904e8db864c07585ef99875/psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b" }, + { url = "http://mirrors.aliyun.com/pypi/packages/d6/f5/97baea3fe7a5a9af7436301f85490905379b1c6f2dd51fe3ecf24b4c5fbf/psutil-7.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea" }, + { url = "http://mirrors.aliyun.com/pypi/packages/37/d6/246513fbf9fa174af531f28412297dd05241d97a75911ac8febefa1a53c6/psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63" }, + { url = "http://mirrors.aliyun.com/pypi/packages/b8/b5/9182c9af3836cca61696dabe4fd1304e17bc56cb62f17439e1154f225dd3/psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312" }, + { url = "http://mirrors.aliyun.com/pypi/packages/16/ba/0756dca669f5a9300d0cbcbfae9a4c30e446dfc7440ffe43ded5724bfd93/psutil-7.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b" }, + { url = "http://mirrors.aliyun.com/pypi/packages/1c/61/8fa0e26f33623b49949346de05ec1ddaad02ed8ba64af45f40a147dbfa97/psutil-7.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9" }, + { url = "http://mirrors.aliyun.com/pypi/packages/81/69/ef179ab5ca24f32acc1dac0c247fd6a13b501fd5534dbae0e05a1c48b66d/psutil-7.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00" }, + { url = "http://mirrors.aliyun.com/pypi/packages/7b/64/665248b557a236d3fa9efc378d60d95ef56dd0a490c2cd37dafc7660d4a9/psutil-7.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9" }, + { url = "http://mirrors.aliyun.com/pypi/packages/d5/2e/e6782744700d6759ebce3043dcfa661fb61e2fb752b91cdeae9af12c2178/psutil-7.2.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a" }, + { url = "http://mirrors.aliyun.com/pypi/packages/57/49/0a41cefd10cb7505cdc04dab3eacf24c0c2cb158a998b8c7b1d27ee2c1f5/psutil-7.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf" }, + { url = "http://mirrors.aliyun.com/pypi/packages/dd/2c/ff9bfb544f283ba5f83ba725a3c5fec6d6b10b8f27ac1dc641c473dc390d/psutil-7.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1" }, + { url = "http://mirrors.aliyun.com/pypi/packages/f2/fc/f8d9c31db14fcec13748d373e668bc3bed94d9077dbc17fb0eebc073233c/psutil-7.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841" }, + { url = "http://mirrors.aliyun.com/pypi/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486" }, + { url = "http://mirrors.aliyun.com/pypi/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979" }, + { url = "http://mirrors.aliyun.com/pypi/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9" }, + { url = "http://mirrors.aliyun.com/pypi/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e" }, + { url = "http://mirrors.aliyun.com/pypi/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8" }, + { url = "http://mirrors.aliyun.com/pypi/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc" }, + { url = "http://mirrors.aliyun.com/pypi/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl", hash = "sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988" }, + { url = "http://mirrors.aliyun.com/pypi/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee" }, +] + +[[package]] +name = "pydantic" +version = "2.13.3" +source = { registry = "http://mirrors.aliyun.com/pypi/simple/" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "http://mirrors.aliyun.com/pypi/packages/d9/e4/40d09941a2cebcb20609b86a559817d5b9291c49dd6f8c87e5feffbe703a/pydantic-2.13.3.tar.gz", hash = "sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d" } +wheels = [ + { url = "http://mirrors.aliyun.com/pypi/packages/f3/0a/fd7d723f8f8153418fb40cf9c940e82004fce7e987026b08a68a36dd3fe7/pydantic-2.13.3-py3-none-any.whl", hash = "sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927" }, +] + +[[package]] +name = "pydantic-core" +version = "2.46.3" +source = { registry = "http://mirrors.aliyun.com/pypi/simple/" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "http://mirrors.aliyun.com/pypi/packages/2a/ef/f7abb56c49382a246fd2ce9c799691e3c3e7175ec74b14d99e798bcddb1a/pydantic_core-2.46.3.tar.gz", hash = "sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c" } +wheels = [ + { url = "http://mirrors.aliyun.com/pypi/packages/22/a2/1ba90a83e85a3f94c796b184f3efde9c72f2830dcda493eea8d59ba78e6d/pydantic_core-2.46.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5" }, + { url = "http://mirrors.aliyun.com/pypi/packages/b6/f6/99ae893c89a0b9d3daec9f95487aa676709aa83f67643b3f0abaf4ab628a/pydantic_core-2.46.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c" }, + { url = "http://mirrors.aliyun.com/pypi/packages/3e/b8/2e8e636dc9e3f16c2e16bf0849e24be82c5ee82c603c65fc0326666328fc/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e" }, + { url = "http://mirrors.aliyun.com/pypi/packages/34/36/0e730beec4d83c5306f417afbd82ff237d9a21e83c5edf675f31ed84c1fe/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287" }, + { url = "http://mirrors.aliyun.com/pypi/packages/4b/f0/3071131f47e39136a17814576e0fada9168569f7f8c0e6ac4d1ede6a4958/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe" }, + { url = "http://mirrors.aliyun.com/pypi/packages/2f/a9/a2dc023eec5aa4b02a467874bad32e2446957d2adcab14e107eab502e978/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050" }, + { url = "http://mirrors.aliyun.com/pypi/packages/0a/44/93f489d16fb63fbd41c670441536541f6e8cfa1e5a69f40bc9c5d30d8c90/pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2" }, + { url = "http://mirrors.aliyun.com/pypi/packages/2a/78/8692e3aa72b2d004f7a5d937f1dfdc8552ba26caf0bec75f342c40f00dec/pydantic_core-2.46.3-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa" }, + { url = "http://mirrors.aliyun.com/pypi/packages/6a/62/e83133f2e7832532060175cebf1f13748f4c7e7e7165cdd1f611f174494b/pydantic_core-2.46.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c" }, + { url = "http://mirrors.aliyun.com/pypi/packages/6d/ec/6a500e3ad7718ee50583fae79c8651f5d37e3abce1fa9ae177ae65842c53/pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf" }, + { url = "http://mirrors.aliyun.com/pypi/packages/d8/53/8267811054b1aa7fc1dc7ded93812372ef79a839f5e23558136a6afbfde1/pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b" }, + { url = "http://mirrors.aliyun.com/pypi/packages/c8/c1/1c0acdb3aa0856ddc4ecc55214578f896f2de16f400cf51627eb3c26c1c4/pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e" }, + { url = "http://mirrors.aliyun.com/pypi/packages/f0/d0/ef39cd0f4a926814f360e71c1adeab48ad214d9727e4deb48eedfb5bce1a/pydantic_core-2.46.3-cp311-cp311-win32.whl", hash = "sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb" }, + { url = "http://mirrors.aliyun.com/pypi/packages/18/9c/f41951b0d858e343f1cf09398b2a7b3014013799744f2c4a8ad6a3eec4f2/pydantic_core-2.46.3-cp311-cp311-win_amd64.whl", hash = "sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346" }, + { url = "http://mirrors.aliyun.com/pypi/packages/9f/1e/264a17cd582f6ed50950d4d03dd5fefd84e570e238afe1cb3e25cf238769/pydantic_core-2.46.3-cp311-cp311-win_arm64.whl", hash = "sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6" }, + { url = "http://mirrors.aliyun.com/pypi/packages/4b/cb/5b47425556ecc1f3fe18ed2a0083188aa46e1dd812b06e406475b3a5d536/pydantic_core-2.46.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67" }, + { url = "http://mirrors.aliyun.com/pypi/packages/a1/4f/2fb62c2267cae99b815bbf4a7b9283812c88ca3153ef29f7707200f1d4e5/pydantic_core-2.46.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089" }, + { url = "http://mirrors.aliyun.com/pypi/packages/50/6e/b7348fd30d6556d132cddd5bd79f37f96f2601fe0608afac4f5fb01ec0b3/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0" }, + { url = "http://mirrors.aliyun.com/pypi/packages/82/11/31d60ee2b45540d3fb0b29302a393dbc01cd771c473f5b5147bcd353e593/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789" }, + { url = "http://mirrors.aliyun.com/pypi/packages/8a/db/3a9d1957181b59258f44a2300ab0f0be9d1e12d662a4f57bb31250455c52/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d" }, + { url = "http://mirrors.aliyun.com/pypi/packages/9c/e1/3277c38792aeb5cfb18c2f0c5785a221d9ff4e149abbe1184d53d5f72273/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c" }, + { url = "http://mirrors.aliyun.com/pypi/packages/5e/d5/e3d9717c9eba10855325650afd2a9cba8e607321697f18953af9d562da2f/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395" }, + { url = "http://mirrors.aliyun.com/pypi/packages/a1/20/abac35dedcbfd66c6f0b03e4e3564511771d6c9b7ede10a362d03e110d9b/pydantic_core-2.46.3-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396" }, + { url = "http://mirrors.aliyun.com/pypi/packages/6c/a5/41bfd1df69afad71b5cf0535055bccc73022715ad362edbc124bc1e021d7/pydantic_core-2.46.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d" }, + { url = "http://mirrors.aliyun.com/pypi/packages/79/65/38d86ea056b29b2b10734eb23329b7a7672ca604df4f2b6e9c02d4ee22fe/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca" }, + { url = "http://mirrors.aliyun.com/pypi/packages/b6/55/a1129141678a2026badc539ad1dee0a71d06f54c2f06a4bd68c030ac781b/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976" }, + { url = "http://mirrors.aliyun.com/pypi/packages/d7/60/cb26f4077719f709e54819f4e8e1d43f4091f94e285eb6bd21e1190a7b7c/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b" }, + { url = "http://mirrors.aliyun.com/pypi/packages/6b/7e/c3f21882bdf1d8d086876f81b5e296206c69c6082551d776895de7801fa0/pydantic_core-2.46.3-cp312-cp312-win32.whl", hash = "sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4" }, + { url = "http://mirrors.aliyun.com/pypi/packages/57/be/6b5e757b859013ebfbd7adba02f23b428f37c86dcbf78b5bb0b4ffd36e99/pydantic_core-2.46.3-cp312-cp312-win_amd64.whl", hash = "sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1" }, + { url = "http://mirrors.aliyun.com/pypi/packages/bf/f8/a989b21cc75e9a32d24192ef700eea606521221a89faa40c919ce884f2b1/pydantic_core-2.46.3-cp312-cp312-win_arm64.whl", hash = "sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72" }, + { url = "http://mirrors.aliyun.com/pypi/packages/9b/3c/9b5e8eb9821936d065439c3b0fb1490ffa64163bfe7e1595985a47896073/pydantic_core-2.46.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37" }, + { url = "http://mirrors.aliyun.com/pypi/packages/91/97/1c41d1f5a19f241d8069f1e249853bcce378cdb76eec8ab636d7bc426280/pydantic_core-2.46.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f" }, + { url = "http://mirrors.aliyun.com/pypi/packages/30/b4/d03a7ae14571bc2b6b3c7b122441154720619afe9a336fa3a95434df5e2f/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8" }, + { url = "http://mirrors.aliyun.com/pypi/packages/ae/0c/4086f808834b59e3c8f1aa26df8f4b6d998cdcf354a143d18ef41529d1fe/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad" }, + { url = "http://mirrors.aliyun.com/pypi/packages/fa/71/a649be5a5064c2df0db06e0a512c2281134ed2fcc981f52a657936a7527c/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c" }, + { url = "http://mirrors.aliyun.com/pypi/packages/a2/84/7756e75763e810b3a710f4724441d1ecc5883b94aacb07ca71c5fb5cfb69/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f" }, + { url = "http://mirrors.aliyun.com/pypi/packages/6c/35/68a762e0c1e31f35fa0dac733cbd9f5b118042853698de9509c8e5bf128b/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35" }, + { url = "http://mirrors.aliyun.com/pypi/packages/77/bf/1bf8c9a8e91836c926eae5e3e51dce009bf495a60ca56060689d3df3f340/pydantic_core-2.46.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687" }, + { url = "http://mirrors.aliyun.com/pypi/packages/e5/50/87d818d6bab915984995157ceb2380f5aac4e563dddbed6b56f0ed057aba/pydantic_core-2.46.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3" }, + { url = "http://mirrors.aliyun.com/pypi/packages/91/88/a311fb306d0bd6185db41fa14ae888fb81d0baf648a761ae760d30819d33/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022" }, + { url = "http://mirrors.aliyun.com/pypi/packages/8f/79/28fd0d81508525ab2054fef7c77a638c8b5b0afcbbaeee493cf7c3fef7e1/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23" }, + { url = "http://mirrors.aliyun.com/pypi/packages/b3/21/795bf5fe5c0f379308b8ef19c50dedab2e7711dbc8d0c2acf08f1c7daa05/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7" }, + { url = "http://mirrors.aliyun.com/pypi/packages/45/b3/ed14c659cbe7605e3ef063077680a64680aec81eb1a04763a05190d49b7f/pydantic_core-2.46.3-cp313-cp313-win32.whl", hash = "sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13" }, + { url = "http://mirrors.aliyun.com/pypi/packages/ef/bb/adb70d9a762ddd002d723fbf1bd492244d37da41e3af7b74ad212609027e/pydantic_core-2.46.3-cp313-cp313-win_amd64.whl", hash = "sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0" }, + { url = "http://mirrors.aliyun.com/pypi/packages/52/eb/66faefabebfe68bd7788339c9c9127231e680b11906368c67ce112fdb47f/pydantic_core-2.46.3-cp313-cp313-win_arm64.whl", hash = "sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec" }, + { url = "http://mirrors.aliyun.com/pypi/packages/7f/db/a7bcb4940183fda36022cd18ba8dd12f2dff40740ec7b58ce7457befa416/pydantic_core-2.46.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b" }, + { url = "http://mirrors.aliyun.com/pypi/packages/24/35/e4066358a22e3e99519db370494c7528f5a2aa1367370e80e27e20283543/pydantic_core-2.46.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018" }, + { url = "http://mirrors.aliyun.com/pypi/packages/87/92/37cf4049d1636996e4b888c05a501f40a43ff218983a551d57f9d5e14f0d/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34" }, + { url = "http://mirrors.aliyun.com/pypi/packages/d8/36/9ff4d676dfbdfb2d591cf43f3d90ded01e15b1404fd101180ed2d62a2fd3/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7" }, + { url = "http://mirrors.aliyun.com/pypi/packages/bc/f0/405b442a4d7ba855b06eec8b2bf9c617d43b8432d099dfdc7bf999293495/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2" }, + { url = "http://mirrors.aliyun.com/pypi/packages/e7/f8/65cd92dd5a0bd89ba277a98ecbfaf6fc36bbd3300973c7a4b826d6ab1391/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba" }, + { url = "http://mirrors.aliyun.com/pypi/packages/fd/86/ef96a4c6e79e7a2d0410826a68fbc0eccc0fd44aa733be199d5fcac3bb87/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f" }, + { url = "http://mirrors.aliyun.com/pypi/packages/6d/53/269caf30e0096e0a8a8f929d1982a27b3879872cca2d917d17c2f9fdf4fe/pydantic_core-2.46.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22" }, + { url = "http://mirrors.aliyun.com/pypi/packages/00/b0/1a6d9b6a587e118482910c244a1c5acf4d192604174132efd12bf0ac486f/pydantic_core-2.46.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f" }, + { url = "http://mirrors.aliyun.com/pypi/packages/87/56/e7e00d4041a7e62b5a40815590114db3b535bf3ca0bf4dca9f16cef25246/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127" }, + { url = "http://mirrors.aliyun.com/pypi/packages/e8/22/4bd23c3d41f7c185d60808a1de83c76cf5aeabf792f6c636a55c3b1ec7f9/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c" }, + { url = "http://mirrors.aliyun.com/pypi/packages/24/ac/66cd45129e3915e5ade3b292cb3bc7fd537f58f8f8dbdaba6170f7cabb74/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1" }, + { url = "http://mirrors.aliyun.com/pypi/packages/a2/51/dd4248abb84113615473aa20d5545b7c4cd73c8644003b5259686f93996c/pydantic_core-2.46.3-cp314-cp314-win32.whl", hash = "sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505" }, + { url = "http://mirrors.aliyun.com/pypi/packages/20/eb/59980e5f1ae54a3b86372bd9f0fa373ea2d402e8cdcd3459334430f91e91/pydantic_core-2.46.3-cp314-cp314-win_amd64.whl", hash = "sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e" }, + { url = "http://mirrors.aliyun.com/pypi/packages/8c/db/1cf77e5247047dfee34bc01fa9bca134854f528c8eb053e144298893d370/pydantic_core-2.46.3-cp314-cp314-win_arm64.whl", hash = "sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df" }, + { url = "http://mirrors.aliyun.com/pypi/packages/57/c0/b3df9f6a543276eadba0a48487b082ca1f201745329d97dbfa287034a230/pydantic_core-2.46.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf" }, + { url = "http://mirrors.aliyun.com/pypi/packages/66/57/886a938073b97556c168fd99e1a7305bb363cd30a6d2c76086bf0587b32a/pydantic_core-2.46.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee" }, + { url = "http://mirrors.aliyun.com/pypi/packages/0b/7c/b42eaa5c34b13b07ecb51da21761297a9b8eb43044c864a035999998f328/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a" }, + { url = "http://mirrors.aliyun.com/pypi/packages/e6/9b/92b42db6543e7de4f99ae977101a2967b63122d4b6cf7773812da2d7d5b5/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c" }, + { url = "http://mirrors.aliyun.com/pypi/packages/0f/19/46fbe1efabb5aa2834b43b9454e70f9a83ad9c338c1291e48bdc4fecf167/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1" }, + { url = "http://mirrors.aliyun.com/pypi/packages/77/da/b3f95bc009ad60ec53120f5d16c6faa8cabdbe8a20d83849a1f2b8728148/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64" }, + { url = "http://mirrors.aliyun.com/pypi/packages/cc/6e/401336117722e28f32fb8220df676769d28ebdf08f2f4469646d404c43a3/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb" }, + { url = "http://mirrors.aliyun.com/pypi/packages/fc/53/b289f9bc8756a32fe718c46f55afaeaf8d489ee18d1a1e7be1db73f42cc4/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6" }, + { url = "http://mirrors.aliyun.com/pypi/packages/10/5b/8292fc7c1f9111f1b2b7c1b0dcf1179edcd014fc3ea4517499f50b829d71/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c" }, + { url = "http://mirrors.aliyun.com/pypi/packages/2b/9e/f80044e9ec07580f057a89fc131f78dda7a58751ddf52bbe05eaf31db50f/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47" }, + { url = "http://mirrors.aliyun.com/pypi/packages/f8/84/6781a1b037f3b96be9227edbd1101f6d3946746056231bf4ac48cdff1a8d/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab" }, + { url = "http://mirrors.aliyun.com/pypi/packages/3e/db/19c0839feeb728e7df03255581f198dfdf1c2aeb1e174a8420b63c5252e5/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba" }, + { url = "http://mirrors.aliyun.com/pypi/packages/e0/15/3228774cb7cd45f5f721ddf1b2242747f4eb834d0c491f0c02d606f09fed/pydantic_core-2.46.3-cp314-cp314t-win32.whl", hash = "sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56" }, + { url = "http://mirrors.aliyun.com/pypi/packages/b8/2a/c79cf53fd91e5a87e30d481809f52f9a60dd221e39de66455cf04deaad37/pydantic_core-2.46.3-cp314-cp314t-win_amd64.whl", hash = "sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8" }, + { url = "http://mirrors.aliyun.com/pypi/packages/0b/db/d8182a7f1d9343a032265aae186eb063fe26ca4c40f256b21e8da4498e89/pydantic_core-2.46.3-cp314-cp314t-win_arm64.whl", hash = "sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374" }, + { url = "http://mirrors.aliyun.com/pypi/packages/66/7f/03dbad45cd3aa9083fbc93c210ae8b005af67e4136a14186950a747c6874/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46" }, + { url = "http://mirrors.aliyun.com/pypi/packages/26/22/4dc186ac8ea6b257e9855031f51b62a9637beac4d68ac06bee02f046f836/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874" }, + { url = "http://mirrors.aliyun.com/pypi/packages/0d/ca/d376391a5aff1f2e8188960d7873543608130a870961c2b6b5236627c116/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76" }, + { url = "http://mirrors.aliyun.com/pypi/packages/0e/6b/523b9f85c23788755d6ab949329de692a2e3a584bc6beb67fef5e035aa9d/pydantic_core-2.46.3-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531" }, + { url = "http://mirrors.aliyun.com/pypi/packages/34/42/f426db557e8ab2791bc7562052299944a118655496fbff99914e564c0a94/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803" }, + { url = "http://mirrors.aliyun.com/pypi/packages/5c/4f/86a832a9d14df58e663bfdf4627dc00d3317c2bd583c4fb23390b0f04b8e/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3" }, + { url = "http://mirrors.aliyun.com/pypi/packages/11/1a/fe857968954d93fb78e0d4b6df5c988c74c4aaa67181c60be7cfe327c0ca/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5" }, + { url = "http://mirrors.aliyun.com/pypi/packages/17/eb/9d89ad2d9b0ba8cd65393d434471621b98912abb10fbe1df08e480ba57b5/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4" }, + { url = "http://mirrors.aliyun.com/pypi/packages/1f/da/99d40830684f81dec901cac521b5b91c095394cc1084b9433393cde1c2df/pydantic_core-2.46.3-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25" }, + { url = "http://mirrors.aliyun.com/pypi/packages/99/a5/87024121818d75bbb2a98ddbaf638e40e7a18b5e0f5492c9ca4b1b316107/pydantic_core-2.46.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3" }, + { url = "http://mirrors.aliyun.com/pypi/packages/60/62/0c1acfe10945b83a6a59d19fbaa92f48825381509e5701b855c08f13db76/pydantic_core-2.46.3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536" }, + { url = "http://mirrors.aliyun.com/pypi/packages/75/3e/3b2393b4c8f44285561dc30b00cf307a56a2eff7c483a824db3b8221ca51/pydantic_core-2.46.3-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1" }, + { url = "http://mirrors.aliyun.com/pypi/packages/ba/75/5af02fb35505051eee727c061f2881c555ab4f8ddb2d42da715a42c9731b/pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c" }, + { url = "http://mirrors.aliyun.com/pypi/packages/10/92/7e0e1bd9ca3c68305db037560ca2876f89b2647deb2f8b6319005de37505/pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85" }, + { url = "http://mirrors.aliyun.com/pypi/packages/b8/d8/101655f27eaf3e44558ead736b2795d12500598beed4683f279396fa186e/pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8" }, + { url = "http://mirrors.aliyun.com/pypi/packages/07/0f/1c34a74c8d07136f0d729ffe5e1fdab04fbdaa7684f61a92f92511a84a15/pydantic_core-2.46.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff" }, +] + +[[package]] +name = "pythonpractice" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "mypy" }, + { name = "objgraph" }, + { name = "psutil" }, + { name = "pydantic" }, +] + +[package.metadata] +requires-dist = [ + { name = "mypy", specifier = ">=1.20.2" }, + { name = "objgraph", specifier = ">=3.6.2" }, + { name = "psutil", specifier = ">=7.2.2" }, + { name = "pydantic", specifier = ">=2.13.3" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "http://mirrors.aliyun.com/pypi/simple/" } +sdist = { url = "http://mirrors.aliyun.com/pypi/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466" } +wheels = [ + { url = "http://mirrors.aliyun.com/pypi/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "http://mirrors.aliyun.com/pypi/simple/" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "http://mirrors.aliyun.com/pypi/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464" } +wheels = [ + { url = "http://mirrors.aliyun.com/pypi/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7" }, +]