微软Channel 9 Python入门教程:从零开始掌握Python编程基础
微软Channel 9的Python for Beginners系列课程是一个精心设计的入门教程,专为有一定编程经验但希望学习Python的开发人员打造。该系列采用循序渐进的教学方式,通过18个核心模块全面覆盖Python编程基础,从最简单的打印语句到复杂的API调用和JSON处理,帮助学员系统性地掌握Python编程。
Python for Beginners系列课程概述
微软Channel 9的Python for Beginners系列课程是一个精心设计的入门教程,专为有一定编程经验但希望学习Python的开发人员打造。该系列采用循序渐进的教学方式,通过18个核心模块全面覆盖Python编程基础。
课程体系结构
整个Python for Beginners系列采用模块化设计,每个模块专注于一个特定的编程概念,从最简单的打印语句到复杂的API调用和JSON处理。课程结构如下表所示:
| 模块编号 | 主题内容 | 核心知识点 | 代码示例数量 |
|---|---|---|---|
| 02 | 打印输出 | print语句、字符串格式化 | 6个示例 |
| 03 | 注释 | 单行注释、多行注释、调试技巧 | 5个示例 |
| 04 | 字符串变量 | 字符串操作、格式化、函数 | 6个示例 |
| 05 | 数值变量 | 数学运算、类型转换 | 7个示例 |
| 06 | 日期处理 | datetime模块、日期格式化 | 6个示例 |
| 07 | 错误处理 | 语法错误、运行时错误、逻辑错误 | 3个示例 |
| 08 | 条件判断 | if语句、比较操作 | 7个示例 |
| 09 | 多重条件 | elif、嵌套条件、逻辑运算符 | 8个示例 |
| 10 | 复杂条件 | 布尔变量、and/or运算 | 5个示例 |
| 11 | 集合类型 | 列表、字典、数组、范围 | 5个示例 |
| 12 | 循环结构 | for循环、while循环 | 3个示例 |
| 13 | 函数基础 | 函数定义、参数传递 | 11个示例 |
| 14 | 函数参数 | 默认参数、命名参数、多参数 | 8个示例 |
| 15 | 包管理 | 模块导入、requirements.txt | 4个示例 |
| 16 | API调用 | HTTP请求、REST API | 3个示例 |
| 17 | JSON处理 | json模块、数据序列化 | 8个示例 |
| 18 | 装饰器 | 函数装饰器基础 | 2个示例 |
教学特色与优势
该系列课程具有以下显著特点:
实践导向的教学方法:每个概念都配有完整的代码示例,学员可以通过实际操作来巩固学习成果。例如在函数模块中,提供了从简单打印函数到复杂参数处理的11个不同示例。
# 函数基础示例 - 获取姓名首字母
def get_initials(first_name, middle_name, last_name):
"""获取姓名的首字母"""
return f"{first_name[0]}{middle_name[0]}{last_name[0]}"
# 使用示例
initials = get_initials("John", "Michael", "Doe")
print(f"Initials: {initials}") # 输出: JMD
循序渐进的学习曲线:课程从最简单的"Hello World"开始,逐步引入更复杂的概念,确保学员能够平稳过渡。
graph TD
A[打印输出] --> B[变量与数据类型]
B --> C[条件判断]
C --> D[循环结构]
D --> E[函数定义]
E --> F[模块与包]
F --> G[API调用]
G --> H[数据处理]
真实场景的应用示例:课程中的代码示例都来源于实际开发场景,如处理用户输入、格式化输出、调用外部API等,让学员能够立即将所学知识应用到实际项目中。
学习路径设计
课程采用精心设计的学习路径,确保学员能够系统性地掌握Python编程:
- 基础语法阶段(模块02-06):掌握Python的基本语法和数据类型
- 控制结构阶段(模块07-12):学习程序流程控制和错误处理
- 函数模块阶段(模块13-15):深入理解函数设计和模块化编程
- 高级应用阶段(模块16-18):探索API集成和数据处理技术
每个模块都包含:
- 理论知识讲解
- 多个代码示例
- 编程挑战题目
- 解决方案参考
- 相关的PPT教学材料
配套资源与扩展
除了核心的18个模块外,该系列还提供了丰富的配套资源:
- 幻灯片教学材料:每个主题都有对应的PPT文件,便于复习和教学使用
- 编程挑战题目:每个模块都包含编码挑战,帮助学员检验学习成果
- 解决方案代码:提供完整的挑战解决方案,便于对比和学习
- 扩展学习指南:推荐后续学习路径和进阶资源
该课程特别适合有以下背景的学习者:
- 已有其他编程语言经验(如JavaScript、Java、C#)
- 希望快速掌握Python语法和核心概念
- 准备进入Web开发、数据分析或机器学习领域
- 使用Visual Studio Code作为开发环境
通过这个系列的学习,学员不仅能够掌握Python编程基础,还能为后续的"More Python for Beginners"和"Even More Python for Beginners"系列课程打下坚实基础,逐步深入到面向对象编程、异步编程和数据科学等高级主题。
基础语法:打印、变量和数据类型
Python作为一门简洁优雅的编程语言,其基础语法设计非常直观易懂。掌握打印输出、变量声明和数据类型是学习Python编程的第一步,也是构建复杂程序的基础。让我们深入探索这些核心概念。
打印输出:与程序对话的窗口
在Python中,print()函数是我们与程序交互的主要方式,它可以将信息输出到控制台。这个看似简单的函数却蕴含着丰富的功能。
基础打印语法
# 最简单的打印语句
print('Hello world')
# 使用双引号也是可以的
print("Hello world double quotes")
# 打印空行
print()
print('Did you see that blank line?')
特殊字符和格式化
# 使用转义字符\n换行
print('Blank line \nin the middle of string')
# 打印多个参数,默认用空格分隔
print('Hello', 'world', '!') # 输出: Hello world !
# 修改分隔符
print('2023', '12', '25', sep='-') # 输出: 2023-12-25
打印流程图
flowchart TD
A[调用print函数] --> B{参数处理}
B --> C[转换为字符串]
C --> D[添加分隔符sep]
D --> E[添加结束符end]
E --> F[输出到控制台]
F --> G[完成打印]
变量:数据的容器
变量是编程中存储和操作数据的基本单元。Python的变量声明非常简洁,无需显式指定类型。
变量命名规则
遵循PEP-8命名规范:
- 使用小写字母和下划线:
first_name - 避免使用Python关键字
- 具有描述性的名称
# 字符串变量
first_name = 'Susan'
last_name = "Ibach"
# 数值变量
age = 25
height = 175.5
# 布尔变量
is_student = True
has_job = False
变量操作示例
# 变量重新赋值
counter = 1
print(counter) # 输出: 1
counter = counter + 1
print(counter) # 输出: 2
# 多重赋值
x, y, z = 1, 2, 3
print(x, y, z) # 输出: 1 2 3
数据类型:Python的构建块
Python具有丰富的数据类型系统,理解这些类型对于编写正确的程序至关重要。
基本数据类型对比
| 数据类型 | 示例 | 描述 | 可变性 |
|---|---|---|---|
| int | 42, -7, 0 |
整数值 | 不可变 |
| float | 3.14, -0.5, 2.0 |
浮点数值 | 不可变 |
| str | 'hello', "world" |
字符串 | 不可变 |
| bool | True, False |
布尔值 | 不可变 |
| NoneType | None |
空值 | 不可变 |
类型转换操作
# 字符串转数字
num_str = "42"
num_int = int(num_str) # 转换为整数: 42
num_float = float(num_str) # 转换为浮点数: 42.0
# 数字转字符串
age = 25
age_str = str(age) # 转换为字符串: "25"
# 布尔转换
truthy = bool(1) # True
falsy = bool(0) # False
数据类型关系图
classDiagram
class DataType {
<<abstract>>
+value
+convert()
}
class NumericType {
<<abstract>>
+arithmetic_operations()
}
class IntType {
+whole_numbers
+bit_operations()
}
class FloatType {
+decimal_numbers
+rounding()
}
class StringType {
+text_data
+concatenation()
+formatting()
}
class BoolType {
+logical_values
+logical_operations()
}
DataType <|-- NumericType
DataType <|-- StringType
DataType <|-- BoolType
NumericType <|-- IntType
NumericType <|-- FloatType
字符串操作:文本处理的艺术
字符串是编程中最常用的数据类型之一,Python提供了丰富的字符串操作方法。
字符串拼接和格式化
first_name = 'Susan'
last_name = 'Ibach'
# 使用+运算符拼接
full_name = first_name + ' ' + last_name
print(full_name) # 输出: Susan Ibach
# 使用f-string格式化(Python 3.6+)
greeting = f'Hello {first_name} {last_name}!'
print(greeting) # 输出: Hello Susan Ibach!
# 字符串方法操作
print(first_name.upper()) # 输出: SUSAN
print(last_name.lower()) # 输出: ibach
print(full_name.capitalize()) # 输出: Susan ibach
用户输入处理
# 获取用户输入
name = input('What is your name? ')
age = input('How old are you? ')
# 处理输入数据
print(f'Hello {name.capitalize()}!')
print(f'Next year you will be {int(age) + 1} years old.')
数值运算:数学计算的基础
Python支持各种数学运算,从简单的算术到复杂的数学函数。
基本算术运算
# 基本运算
a = 10
b = 3
print('加法:', a + b) # 13
print('减法:', a - b) # 7
print('乘法:', a * b) # 30
print('除法:', a / b) # 3.333...
print('整除:', a // b) # 3
print('取余:', a % b) # 1
print('幂运算:', a ** b) # 1000
数值运算优先级
flowchart LR
A[表达式] --> B[括号]
B --> C[指数]
C --> D[乘除]
D --> E[加减]
E --> F[结果]
混合类型运算
# 数值与字符串的交互
days_in_feb = 28
# 错误示例:类型不匹配
# print(days_in_feb + ' days in February') # TypeError
# 正确示例:类型转换
print(str(days_in_feb) + ' days in February') # 28 days in February
# 使用f-string避免转换
print(f'{days_in_feb} days in February') # 28 days in February
最佳实践和常见陷阱
变量命名最佳实践
# 好的命名
student_name = "Alice"
exam_score = 95
is_passed = True
# 不好的命名
n = "Alice" # 不具描述性
sc = 95 # 缩写不明确
ip = True # 含义模糊
类型安全操作
# 安全的类型检查
value = input('Enter a number: ')
if value.isdigit():
number = int(value)
print(f'Square: {number ** 2}')
else:
print('Please enter a valid number!')
# 使用try-except处理转换错误
try:
num = float(input('Enter a decimal number: '))
print(f'Reciprocal: {1 / num}')
except ValueError:
print('Invalid number format!')
except ZeroDivisionError:
print('Cannot divide by zero!')
内存管理示意图
flowchart TD
A[变量声明] --> B[内存分配]
B --> C[值存储]
C --> D[引用创建]
D --> E[操作执行]
E --> F{需要更多内存?}
F -->|是| G[内存重新分配]
F -->|否| H[操作完成]
G --> C
通过掌握这些基础语法概念,你已经建立了坚实的Python编程基础。打印输出让你能够与程序交互,变量提供了数据存储的机制,而数据类型确保了操作的准确性和效率。这些基础构建块将为学习更复杂的Python特性奠定坚实的基础。
条件判断和循环控制结构
Python编程中的条件判断和循环控制结构是构建逻辑流程的核心工具。它们让程序能够根据不同的条件执行不同的代码块,或者重复执行特定的任务,从而实现复杂的业务逻辑和数据处理。
条件判断语句
Python使用if、elif和else关键字来实现条件判断。这些语句让程序能够根据不同的条件执行相应的代码块。
基本if语句
最基本的条件判断使用if语句,语法结构如下:
if condition:
# 条件为真时执行的代码
例如,检查价格是否超过1美元并计算税费:
price = float(input('how much did you pay? '))
if price >= 1.00:
tax = 0.07
print(f'Tax rate is: {tax}')
if-else语句
当需要处理条件不成立的情况时,使用if-else结构:
if condition:
# 条件为真时执行的代码
else:
# 条件为假时执行的代码
price = float(input('how much did you pay? '))
if price >= 1.00:
tax = 0.07
print(f'Tax rate is: {tax}')
else:
tax = 0
print('No tax charged')
多条件判断(if-elif-else)
对于多个互斥条件的情况,使用if-elif-else结构:
if condition1:
# 条件1为真时执行
elif condition2:
# 条件2为真时执行
elif condition3:
# 条件3为真时执行
else:
# 所有条件都不满足时执行
province = input("What province do you live in? ")
tax = 0
if province == 'Alberta':
tax = 0.05
elif province == 'Nunavut':
tax = 0.05
elif province == 'Ontario':
tax = 0.13
else:
tax = 0.10
print(f'Tax rate for {province}: {tax}')
比较运算符
Python提供了丰富的比较运算符用于条件判断:
| 运算符 | 描述 | 示例 |
|---|---|---|
== |
等于 | x == y |
!= |
不等于 | x != y |
> |
大于 | x > y |
< |
小于 | x < y |
>= |
大于等于 | x >= y |
<= |
小于等于 | x <= y |
in |
成员判断 | x in [a, b, c] |
# 使用in运算符简化多条件判断
province = input("What province do you live in? ")
if province in ['Alberta', 'Nunavut', 'Yukon']:
tax = 0.05
elif province == 'Ontario':
tax = 0.13
else:
tax = 0.10
循环控制结构
循环结构允许重复执行代码块,Python提供了for循环和while循环两种主要方式。
for循环
for循环用于遍历序列(如列表、元组、字符串)或其他可迭代对象:
for variable in sequence:
# 循环体代码
# 遍历列表
names = ['Christopher', 'Susan']
for name in names:
print(name)
# 使用range()函数生成数字序列
for index in range(0, 5):
print(f'Index: {index}')
# 遍历字符串
message = "Hello"
for char in message:
print(char)
while循环
while循环在条件为真时重复执行代码块:
while condition:
# 循环体代码
# 基本的while循环
names = ['Christopher', 'Susan']
index = 0
while index < len(names):
print(names[index])
index = index + 1 # 必须改变循环条件
# 计数器控制的循环
count = 0
while count < 5:
print(f'Count: {count}')
count += 1
循环控制流程图
flowchart TD
A[开始循环] --> B{条件判断}
B -- 条件为真 --> C[执行循环体]
C --> D[更新循环条件]
D --> B
B -- 条件为假 --> E[结束循环]
嵌套结构和复杂条件
在实际编程中,经常需要组合使用条件判断和循环:
# 嵌套if语句
country = input("What country do you live in? ")
if country.lower() == 'canada':
province = input("What province do you live in? ")
if province == 'Alberta':
tax = 0.05
elif province == 'Ontario':
tax = 0.13
else:
tax = 0.10
else:
tax = 0.15
print(f'Tax rate: {tax}')
# 循环中的条件判断
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for num in numbers:
if num % 2 == 0:
print(f'{num} is even')
else:
print(f'{num} is odd')
布尔运算符
Python提供了三个布尔运算符来组合多个条件:
| 运算符 | 描述 | 示例 |
|---|---|---|
and |
逻辑与 | x > 0 and x < 10 |
or |
逻辑或 | x == 5 or x == 10 |
not |
逻辑非 | not x > 5 |
# 使用and运算符
age = 25
if age >= 18 and age <= 65:
print("Eligible for work")
# 使用or运算符
province = "Ontario"
if province == "Ontario" or province == "Quebec":
print("Major province")
# 使用not运算符
is_weekend = False
if not is_weekend:
print("It's a work day")
最佳实践和常见错误
- 缩进正确性:Python使用缩进来标识代码块,确保使用一致的缩进(通常4个空格)
- 避免无限循环:在while循环中确保条件最终会变为False
- 使用描述性变量名:使代码更易读
- 简化复杂条件:使用括号明确运算优先级
# 好的实践:清晰的变量名和结构
purchase_amount = float(input('Enter purchase amount: '))
if purchase_amount > 100.00:
discount = 0.10
elif purchase_amount > 50.00:
discount = 0.05
else:
discount = 0.00
final_price = purchase_amount * (1 - discount)
print(f'Final price: ${final_price:.2f}')
条件判断和循环控制结构是Python编程的基础,掌握这些概念对于编写高效、可读的代码至关重要。通过合理的组合使用这些结构,可以构建出处理各种复杂逻辑的程序。
函数定义和模块化编程:构建可重用的Python代码
在Python编程中,函数是代码组织和重用的基本单元。通过将重复的代码逻辑封装到函数中,我们可以创建更加模块化、可维护和可重用的程序。本节将深入探讨Python函数的定义、参数使用以及模块化编程的最佳实践。
函数的基本定义和调用
Python使用def关键字来定义函数,基本语法如下:
def function_name(parameters):
# 函数体代码
return value
让我们通过一个实际的例子来理解函数如何消除重复代码。假设我们需要获取用户姓名的首字母:
# 不使用函数的重复代码
first_name = input('Enter your first name: ')
first_name_initial = first_name[0:1].upper()
middle_name = input('Enter your middle name: ')
middle_name_initial = middle_name[0:1].upper()
last_name = input('Enter your last name: ')
last_name_initial = last_name[0:1].upper()
print('Your initials are: ' + first_name_initial + middle_name_initial + last_name_initial)
通过创建函数,我们可以显著简化代码:
def get_initial(name):
"""获取姓名的首字母并转换为大写"""
initial = name[0:1].upper()
return initial
# 使用函数重构后的代码
first_name = input('Enter your first name: ')
first_name_initial = get_initial(first_name)
middle_name = input('Enter your middle name: ')
middle_name_initial = get_initial(middle_name)
last_name = input('Enter your last name: ')
last_name_initial = get_initial(last_name)
print('Your initials are: ' + first_name_initial + middle_name_initial + last_name_initial)
函数参数的高级用法
Python函数支持多种参数传递方式,让函数更加灵活和强大。
位置参数和默认参数
def get_initial(name, force_uppercase=True):
"""获取姓名的首字母,可选择是否强制大写"""
if force_uppercase:
initial = name[0:1].upper()
else:
initial = name[0:1]
return initial
# 使用默认参数
initial1 = get_initial("John") # 返回 'J'
initial2 = get_initial("John", False) # 返回 'j'
命名参数(关键字参数)
命名参数允许我们以任意顺序传递参数,提高代码的可读性:
def create_user(name, age, email, is_active=True):
"""创建用户信息"""
return {
'name': name,
'age': age,
'email': email,
'is_active': is_active
}
# 使用命名参数
user = create_user(
name="Alice",
email="alice@example.com",
age=25,
is_active=True
)
函数返回值的最佳实践
函数可以返回单个值或多个值(以元组形式)。良好的返回值设计可以让函数更加实用:
def calculate_statistics(numbers):
"""计算数字列表的统计信息"""
if not numbers:
return None
total = sum(numbers)
count = len(numbers)
average = total / count
maximum = max(numbers)
minimum = min(numbers)
return total, count, average, maximum, minimum
# 使用函数返回的多个值
numbers = [10, 20, 30, 40, 50]
total, count, avg, max_val, min_val = calculate_statistics(numbers)
模块化编程:创建可重用的代码库
模块化编程是将代码组织到独立文件中的实践,使得代码更易于维护和重用。
创建自定义模块
首先创建一个名为helpers.py的模块文件:
# helpers.py
def display(message, is_warning=False):
"""显示消息,可选择显示为警告"""
if is_warning:
print('Warning: ' + message)
else:
print('Info: ' + message)
def format_name(first, last, middle=''):
"""格式化姓名"""
if middle:
return f"{first} {middle} {last}"
else:
return f"{first} {last}"
def calculate_discount(price, discount_percent):
"""计算折扣后的价格"""
return price * (1 - discount_percent / 100)
导入和使用模块
有多种方式可以导入和使用模块:
# 方法1: 导入整个模块
import helpers
helpers.display("系统启动完成")
full_name = helpers.format_name("John", "Doe", "Michael")
# 方法2: 导入特定函数
from helpers import display, format_name
display("数据处理中", is_warning=True)
name = format_name("Jane", "Smith")
# 方法3: 导入所有函数(不推荐,可能造成命名冲突)
from helpers import *
discounted_price = calculate_discount(100, 20)
函数设计的最佳实践
为了创建高质量的Python函数,遵循这些最佳实践:
- 单一职责原则:每个函数应该只做一件事
- 清晰的命名:函数名应该准确描述其功能
- 适当的文档:使用docstring说明函数用途和参数
- 参数验证:验证输入参数的合法性
- 错误处理:妥善处理可能出现的异常
def safe_divide(dividend, divisor):
"""
安全除法运算
Args:
dividend: 被除数
divisor: 除数
Returns:
除法结果,如果除数为0则返回None
Raises:
TypeError: 如果参数不是数字类型
"""
if not isinstance(dividend, (int, float)) or not isinstance(divisor, (int, float)):
raise TypeError("参数必须是数字类型")
if divisor == 0:
print("警告:除数为零")
return None
return dividend / divisor
实际应用案例:用户管理系统
让我们创建一个完整的用户管理模块来展示函数和模块化的实际应用:
# user_manager.py
"""用户管理模块"""
users = []
def add_user(name, email, age):
"""添加新用户"""
if not all([name, email, age]):
raise ValueError("所有字段都必须填写")
user = {
'id': len(users) + 1,
'name': name,
'email': email,
'age': age
}
users.append(user)
return user
def get_user_by_id(user_id):
"""根据ID获取用户"""
for user in users:
if user['id'] == user_id:
return user
return None
def get_all_users():
"""获取所有用户"""
return users.copy() # 返回副本以避免直接修改
def delete_user(user_id):
"""删除用户"""
global users
users = [user for user in users if user['id'] != user_id]
return True
# 使用示例
if __name__ == "__main__":
# 添加用户
user1 = add_user("Alice", "alice@example.com", 25)
user2 = add_user("Bob", "bob@example.com", 30)
# 获取用户
all_users = get_all_users()
print(f"总用户数: {len(all_users)}")
# 删除用户
delete_user(1)
print(f"删除后用户数: {len(get_all_users())}")
函数式编程元素
Python也支持函数式编程范式,包括高阶函数和lambda表达式:
# 使用map和lambda处理数据
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared) # [1, 4, 9, 16, 25]
# 使用filter过滤数据
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # [2, 4]
# 使用sorted进行自定义排序
users = [
{'name': 'Alice', 'age': 25},
{'name': 'Bob', 'age': 30},
{'name': 'Charlie', 'age': 20}
]
sorted_users = sorted(users, key=lambda x: x['age'])
print(sorted_users)
通过掌握函数定义和模块化编程的技巧,你可以创建出结构清晰、易于维护的Python应用程序。记住,良好的函数设计是高质量代码的基础。
通过掌握函数定义和模块化编程的技巧,你可以创建出结构清晰、易于维护的Python应用程序。良好的函数设计是高质量代码的基础,这些基础构建块将为学习更复杂的Python特性奠定坚实的基础,帮助学员逐步深入到面向对象编程、异步编程和数据科学等高级主题。
Kimi-K2.5Kimi K2.5 是一款开源的原生多模态智能体模型,它在 Kimi-K2-Base 的基础上,通过对约 15 万亿混合视觉和文本 tokens 进行持续预训练构建而成。该模型将视觉与语言理解、高级智能体能力、即时模式与思考模式,以及对话式与智能体范式无缝融合。Python00
GLM-4.7-FlashGLM-4.7-Flash 是一款 30B-A3B MoE 模型。作为 30B 级别中的佼佼者,GLM-4.7-Flash 为追求性能与效率平衡的轻量化部署提供了全新选择。Jinja00
VLOOKVLOOK™ 是优雅好用的 Typora/Markdown 主题包和增强插件。 VLOOK™ is an elegant and practical THEME PACKAGE × ENHANCEMENT PLUGIN for Typora/Markdown.Less00
PaddleOCR-VL-1.5PaddleOCR-VL-1.5 是 PaddleOCR-VL 的新一代进阶模型,在 OmniDocBench v1.5 上实现了 94.5% 的全新 state-of-the-art 准确率。 为了严格评估模型在真实物理畸变下的鲁棒性——包括扫描伪影、倾斜、扭曲、屏幕拍摄和光照变化——我们提出了 Real5-OmniDocBench 基准测试集。实验结果表明,该增强模型在新构建的基准测试集上达到了 SOTA 性能。此外,我们通过整合印章识别和文本检测识别(text spotting)任务扩展了模型的能力,同时保持 0.9B 的超紧凑 VLM 规模,具备高效率特性。Python00
KuiklyUI基于KMP技术的高性能、全平台开发框架,具备统一代码库、极致易用性和动态灵活性。 Provide a high-performance, full-platform development framework with unified codebase, ultimate ease of use, and dynamic flexibility. 注意:本仓库为Github仓库镜像,PR或Issue请移步至Github发起,感谢支持!Kotlin07
compass-metrics-modelMetrics model project for the OSS CompassPython00