🔎大家好,我是ZTLJQ,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流

📝个人主页-ZTLJQ的主页

🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​📣系列果你对这个系列感兴趣的话

专栏 - ​​​​​​Python从零到企业级应用:短时间成为市场抢手的程序员

✔说明⇢本人讲解主要包括Python爬虫、JS逆向、Python的企业级应用

如果你对这个系列感兴趣的话,可以关注订阅哟👋

在编程的世界里,重复是效率的天敌,混乱是维护的噩梦。而Python,以其优雅和简洁著称,为我们提供了两个强大的武器来对抗这些问题:函数 (Functions) 和 模块 (Modules)。它们是将复杂程序分解为更小、更易管理单元的核心思想,是实现代码复用、提高可读性和可维护性的不二法门。今天,我们将进行一次深度探索,从基础语法到高级技巧,再到实际应用,彻底掌握这两大基石。


第一部分:函数——代码的“乐高积木”

想象一下,你有一个需要反复执行的特定任务,比如计算一个数的平方根,或者格式化一段用户信息。如果每次都需要重写这段逻辑,不仅费时费力,还容易出错。函数就是为此而生的。它是一个命名的代码块,用于执行一个特定的任务。你可以向它传递数据(参数),它处理后返回结果(返回值)。

1. 函数的定义与调用
  • 语法:

    def function_name(parameters):
        """函数文档字符串 (Docstring) - 描述函数的功能"""
        # 函数体 (Function Body)
        # 执行具体操作
        return result  # 可选,用于返回值
  • 关键要素:

    • def: 定义函数的关键字。
    • function_name: 函数名称,应遵循snake_case命名规范,并清晰表达其功能。
    • parameters: 参数列表,位于括号内,多个参数用逗号分隔。参数是函数接收外部数据的占位符。
    • :: 冒号表示函数头结束,函数体开始。
    • 缩进的代码块:所有属于该函数的代码都必须有相同的缩进(通常是4个空格)。
    • return: 关键字,用于退出函数并可选择性地返回一个或多个值给调用者。如果没有return语句,函数默认返回None
2. 参数的奥秘:从简单到灵活

参数是函数灵活性的来源。Python支持多种参数类型:

  • 位置参数 (Positional Arguments):
    最基础的形式。实参(调用时传入的值)按照形参(定义时声明的变量)的顺序一一对应。

    def greet(name, age):
        print(f"Hello, {name}! You are {age} years old.")
    
    # 调用
    greet("Alice", 30)  # 输出: Hello, Alice! You are 30 years old.
    # 注意顺序: "Alice" 对应 name, 30 对应 age
  • 关键字参数 (Keyword Arguments):
    调用函数时,通过参数名=值的方式传递参数。这使得参数顺序不再重要,代码也更具可读性。

    ​
    1# 使用关键字参数调用
    2greet(age=25, name="Bob")  # 输出: Hello, Bob! You are 25 years old.
    3# 顺序可以颠倒,但意义明确
    
    ​
  • 默认参数 (Default Arguments):
    在定义函数时为参数指定一个默认值。如果调用时没有提供该参数,则使用默认值。默认参数必须放在非默认参数之后。

    ​
    1def create_profile(name, city="Unknown", country="China"):
    2    print(f"{name} is from {city}, {country}.")
    3
    4# 调用
    5create_profile("Charlie")                    # 输出: Charlie is from Unknown, China.
    6create_profile("David", "Beijing")          # 输出: David is from Beijing, China. (country用默认值)
    7create_profile("Eve", "Shanghai", "Japan")  # 输出: Eve is from Shanghai, Japan.
    
    ​
  • 可变位置参数 (*args):
    当你不确定函数需要接收多少个位置参数时,可以使用*args。它会将所有额外的位置参数收集到一个元组(tuple)中。

    def sum_all(*numbers):
        """计算任意数量数字的总和"""
        total = 0
        for num in numbers:
            total += num
        return total
    
    # 调用
    print(sum_all(1, 2))           # 输出: 3
    print(sum_all(1, 2, 3, 4, 5))  # 输出: 15
    print(sum_all())               # 输出: 0 (空元组)
    
    # 解包 (Unpacking) 的应用
    my_numbers = [10, 20, 30]
    print(sum_all(*my_numbers))    # 输出: 60 (* 将列表解包成独立的参数)
  • 可变关键字参数 (**kwargs):
    用于接收任意数量的关键字参数。它会将所有额外的关键字参数收集到一个字典(dict)中。

    def build_user_profile(name, **user_info):
        """构建用户资料,接受姓名和任意其他信息"""
        profile = {"name": name}
        profile.update(user_info)  # 将 user_info 字典合并到 profile 中
        return profile
    
    # 调用
    user1 = build_user_profile("Frank", age=35, job="Engineer")
    print(user1)  # 输出: {'name': 'Frank', 'age': 35, 'job': 'Engineer'}
    
    user2 = build_user_profile("Grace", hobby="Reading", city="Hangzhou")
    print(user2)  # 输出: {'name': 'Grace', 'hobby': 'Reading', 'city': 'Hangzhou'}
    
    # 解包 (Unpacking) 的应用
    extra_info = {"level": "Senior", "team": "AI"}
    user3 = build_user_profile("Henry", **extra_info)  # ** 将字典解包成 key=value 形式
    print(user3)  # 输出: {'name': 'Henry', 'level': 'Senior', 'team': 'AI'}
  • 组合使用 (*args 和 **kwargs):
    这是最灵活的函数签名,可以接收几乎任何类型的参数组合。

    def flexible_function(required_param, *args, default_param="default", **kwargs):
        print(f"必需参数: {required_param}")
        print(f"额外位置参数: {args}")
        print(f"默认参数: {default_param}")
        print(f"额外关键字参数: {kwargs}")
    
    # 调用示例
    flexible_function("must_have", 1, 2, 3, optional_kw="value", another="test")
    # 输出:
    # 必需参数: must_have
    # 额外位置参数: (1, 2, 3)
    # 默认参数: default
    # 额外关键字参数: {'optional_kw': 'value', 'another': 'test'}
    
    flexible_function("must_have", 4, 5, default_param="custom", flag=True)
    # 输出:
    # 必需参数: must_have
    # 额外位置参数: (4, 5)
    # 默认参数: custom
    # 额外关键字参数: {'flag': True}
3. 作用域 (Scope):变量的领地

理解变量的作用域至关重要,它决定了变量在何处可以被访问。

  • 局部作用域 (Local Scope): 在函数内部定义的变量。它只能在该函数内部被访问。
  • 全局作用域 (Global Scope): 在函数外部(如模块顶层)定义的变量。它可以在整个模块的任何地方被访问(包括函数内部,但修改时需要特殊处理)。
  • 内置作用域 (Built-in Scope): Python自带的内置函数和异常,如printlenValueError等。

LEGB 规则: 当Python查找一个变量名时,会按照以下顺序搜索:

  1. Local (局部)
  2. Enclosing (嵌套函数的外层函数作用域)
  3. Global (全局)
  4. Built-in (内置)
x = "global x"  # 全局变量

def outer_function():
    y = "outer y"  # 外层函数的局部变量 (对 inner_function 来说是 Enclosing scope)

    def inner_function():
        z = "inner z"  # 局部变量
        print(z)       # -> "inner z" (Local)
        print(y)       # -> "outer y" (Enclosing)
        print(x)       # -> "global x" (Global)
        # print(len)     # -> <built-in function len> (Built-in)

    inner_function()
    print(f"Inside outer, y={y}") # -> Inside outer, y=outer y
    # print(z) # 错误!z 是 inner_function 的局部变量,在此无法访问

outer_function()
print(f"Global x={x}") # -> Global x=global x
# print(y) # 错误!y 是 outer_function 的局部变量,在此无法访问
  • 修改全局变量:global 关键字
    如果你想在函数内部修改一个全局变量,必须使用global关键字声明。

    counter = 0  # 全局计数器
    
    def increment():
        global counter  # 声明要使用全局的 counter
        counter += 1
    
    def bad_increment():
        # counter += 1 # 错误!Python 会认为你在创建一个新的局部变量 counter,
                     # 但在赋值前就试图读取它(UnboundLocalError)
        pass
    
    print(counter) # -> 0
    increment()
    print(counter) # -> 1
    increment()
    print(counter) # -> 2
  • 修改外层变量:nonlocal 关键字
    在嵌套函数中,如果你想修改外层函数的变量,需要使用nonlocal关键字。

    def outer():
        count = 0  # 外层函数的变量
    
        def inner():
            nonlocal count  # 声明要使用外层函数的 count
            count += 1
            return count
    
        return inner  # 返回 inner 函数本身
    
    counter = outer()  # counter 现在是一个闭包 (closure)
    print(counter())   # -> 1
    print(counter())   # -> 2
    print(counter())   # -> 3
    # 每次调用 counter() 都能记住并修改外层的 count 变量
4. 函数是一等公民 (First-Class Citizens)

在Python中,函数是“一等公民”,这意味着它们可以像其他任何对象(如整数、字符串、列表)一样被对待。

  • 将函数赋值给变量:

    def say_hello():
        print("Hello!")
    
    greet = say_hello  # 将函数对象赋值给变量 greet
    greet()             # 调用 -> Hello! (等同于 say_hello())
    print(greet)        # -> <function say_hello at 0x...>
  • 将函数作为参数传递给另一个函数 (高阶函数):

    def apply_operation(func, value):
        """接收一个函数 func 和一个值 value,对 value 应用 func"""
        return func(value)
    
    def square(x):
        return x * x
    
    def double(x):
        return x * 2
    
    result1 = apply_operation(square, 4)  # -> 16
    result2 = apply_operation(double, 4)  # -> 8
    print(result1, result2)
  • 将函数作为另一个函数的返回值:

    def get_multiplier(factor):
        """返回一个能将输入乘以 factor 的函数"""
        def multiplier(number):
            return number * factor
        return multiplier
    
    double_func = get_multiplier(2)
    triple_func = get_multiplier(3)
    
    print(double_func(5))  # -> 10
    print(triple_func(5))  # -> 15
  • 将函数存储在数据结构中:

    operations = [square, double, lambda x: x + 1]  # 列表中存储函数
    values = [1, 2, 3]
    
    for val in values:
        print(f"Operations on {val}:")
        for op in operations:
            print(f"  {op.__name__ if hasattr(op, '__name__') else 'lambda'}({val}) = {op(val)}")
    # 输出类似:
    # Operations on 1:
    #   square(1) = 1
    #   double(1) = 2
    #   lambda(1) = 2
    # ...
5. Lambda 表达式:匿名函数

Lambda表达式是一种创建小型、匿名函数的简洁方式。它适用于简单的、单行的函数逻辑。

  • 语法: lambda arguments: expression
  • 特点: 只能包含一个表达式,不能有复杂的语句(如if-elif-else块,但三元运算符if-else可以)。自动返回表达式的结果。
# 等价于之前的 square 函数
square_lambda = lambda x: x * x
print(square_lambda(4))  # -> 16

# 排序时作为 key 参数
students = [("Alice", 85), ("Bob", 90), ("Charlie", 78)]
# 按成绩 (第二个元素) 升序排序
sorted_by_grade = sorted(students, key=lambda student: student[1])
print(sorted_by_grade) # -> [('Charlie', 78), ('Alice', 85), ('Bob', 90)]

# 结合 map 和 filter
numbers = [1, 2, 3, 4, 5]
# 使用 map 将每个数平方
squared = list(map(lambda x: x**2, numbers))
print(squared) # -> [1, 4, 9, 16, 25]

# 使用 filter 筛选出偶数
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)   # -> [2, 4]
6. 装饰器 (Decorators):为函数“化妆”

装饰器是Python中一个非常强大和优雅的特性。它允许你在不修改原函数代码的情况下,动态地增加其功能(如计时、日志记录、权限检查等)。

  • 本质: 装饰器是一个接收函数作为参数,并返回一个新函数的高阶函数。
  • 语法糖: @decorator_name 用于简化装饰器的应用。
import time

# 一个简单的计时装饰器
def timer_decorator(func):
    """装饰器:测量并打印函数执行时间"""
    def wrapper(*args, **kwargs):  # 包装函数,接收原函数的所有参数
        start_time = time.time()
        result = func(*args, **kwargs)  # 调用原函数
        end_time = time.time()
        print(f"Function '{func.__name__}' took {end_time - start_time:.4f} seconds to execute.")
        return result  # 返回原函数的结果
    return wrapper  # 返回包装后的函数

# 使用 @timer_decorator 装饰 slow_function
@timer_decorator
def slow_function(n):
    """一个模拟耗时操作的函数"""
    total = 0
    for i in range(n):
        total += i
    return total

# 使用 @timer_decorator 装饰 calculate_square
@timer_decorator
def calculate_square(x):
    time.sleep(0.1)  # 模拟一点延迟
    return x * x

# 调用被装饰的函数
result1 = slow_function(1000000)  # 会打印执行时间
result2 = calculate_square(10)    # 会打印执行时间
print(f"Result of slow_function: {result1}")
print(f"Result of calculate_square: {result2}")

输出示例:

Function 'slow_function' took 0.0452 seconds to execute.
Result of slow_function: 499999500000
Function 'calculate_square' took 0.1001 seconds to execute.
Result of calculate_square: 100

解析:

  1. @timer_decorator 写在 slow_function 定义之前。
  2. Python解释器会将其转换为:slow_function = timer_decorator(slow_function)
  3. timer_decorator 函数被调用,传入 slow_function 作为参数。
  4. timer_decorator 内部定义了 wrapper 函数,并返回这个 wrapper 函数。
  5. 因此,slow_function 这个名字现在指向了 wrapper 函数。
  6. 当我们调用 slow_function(1000000) 时,实际上是调用了 wrapper(1000000)
  7. wrapper 函数负责记录时间、调用真正的 slow_function、记录时间并打印,最后返回结果。

第二部分:模块——代码的“文件夹”

随着项目规模的增长,将所有代码塞进一个.py文件里会变得难以管理。模块就是解决这个问题的答案。一个模块就是一个包含Python定义和语句的.py文件。模块的文件名就是模块名(不带.py后缀)。

1. 创建和导入模块
  • 创建模块:
    假设我们创建一个名为 math_utils.py 的文件,其中包含一些数学相关的函数。

    # math_utils.py
    """一个包含实用数学函数的模块。"""
    
    PI = 3.141592653589793
    
    def add(a, b):
        """返回 a 和 b 的和。"""
        return a + b
    
    def multiply(a, b):
        """返回 a 和 b 的积。"""
        return a * b
    
    def circle_area(radius):
        """根据半径计算圆的面积。"""
        return PI * radius ** 2
    
    def _private_helper(x): # 以下划线开头,约定为“私有”函数
        """一个仅供模块内部使用的辅助函数。"""
        return x * 2
  • 导入模块:
    在另一个Python脚本(例如 main.py)中,我们可以导入并使用 math_utils 模块。

    # main.py
    # 方法1: 导入整个模块
    import math_utils
    
    print(math_utils.PI)                # 访问模块中的变量
    print(math_utils.add(5, 3))         # 调用模块中的函数
    area = math_utils.circle_area(4)
    print(f"Area: {area}")
    
    # 方法2: 从模块中导入特定的名称
    from math_utils import add, multiply, PI
    
    print(add(10, 20))      # 直接使用,无需模块前缀
    print(multiply(3, 7))
    print(PI)
    
    # 方法3: 从模块中导入所有名称 (谨慎使用!)
    from math_utils import *
    # 现在可以直接使用 add, multiply, PI, circle_area
    # 但是也导入了 _private_helper,这通常不是好习惯,可能导致命名冲突
    
    # 方法4: 导入并重命名 (as)
    import math_utils as mu
    print(mu.multiply(2, 8)) # 使用别名 mu
    
    from math_utils import circle_area as calc_area
    print(calc_area(5))
2. __name__ 和 __main__:模块的“身份证”

每个Python模块都有一个内置的属性 __name__。它的值取决于模块是如何被使用的。

  • 当一个模块被直接运行时(例如 python math_utils.py),它的 __name__ 属性会被设置为 "__main__"
  • 当一个模块被导入到另一个模块中时,它的 __name__ 属性就是它自己的文件名(如 "math_utils")。

这个特性被广泛用于编写既可以作为脚本独立运行,又可以作为模块被导入的代码。

# 在 math_utils.py 文件末尾添加
if __name__ == "__main__":
    # 这段代码只有在直接运行 math_utils.py 时才会执行
    # 通常用于测试模块中的函数
    print("Running tests for math_utils module:")
    print(f"add(2, 3) = {add(2, 3)}")
    print(f"circle_area(1) = {circle_area(1):.4f}")
    print("All tests passed!")
  • 效果:
    • 如果你执行 python math_utils.py,你会看到测试输出。
    • 如果你在 main.py 中 import math_utils,则不会看到测试输出,只导入了函数和变量。
3. 包 (Packages):模块的“文件夹”

当你的项目变得更大,拥有几十甚至上百个模块时,你需要一个更高层次的组织结构——包 (Package)。一个包就是一个包含多个模块的目录,并且这个目录下必须有一个特殊的文件 __init__.py

  • 创建包:

    my_project/
    ├── __init__.py          # 标记 my_project 是一个包
    ├── calculator.py        # 包内的一个模块
    └── utilities/           # 子包
        ├── __init__.py      # 标记 utilities 是一个子包
        ├── string_utils.py
        └── file_utils.py
  • __init__.py 的作用:

    • 让Python将该目录识别为一个包。
    • 可以包含包初始化代码(当包被首次导入时执行)。
    • 可以控制 from package import * 时导入哪些模块(通过 __all__ 变量)。
    # my_project/__init__.py
    # 可以为空,也可以包含初始化代码
    print("Initializing my_project package...")
    
    # 控制 from my_project import * 的行为
    __all__ = ['calculator']  # 只有 calculator 模块会被 * 导入
  • 从包中导入:

    # main.py (假设在 my_project 目录外)
    
    # 导入包内的模块
    import my_project.calculator
    result = my_project.calculator.add(1, 2)
    
    # 从子包导入
    from my_project.utilities import string_utils
    cleaned_text = string_utils.clean_whitespace("  hello world  ")
    
    # 从子包的模块导入特定函数
    from my_project.utilities.file_utils import read_file, write_file
    
    # 使用相对导入 (通常在包内部的模块间使用)
    # 在 my_project/calculator.py 中
    # from .utilities.string_utils import clean_whitespace  # . 表示当前包
    # from ..other_package import helper_module           # .. 表示上一级
4. Python路径 (sys.path) 与模块搜索

当你导入一个模块时,Python解释器会按照一个特定的顺序去查找它。这个顺序由 sys.path 这个列表决定。

import sys
print(sys.path)

sys.path 通常包含:

  1. 脚本所在的目录(或当前工作目录)。
  2. PYTHONPATH 环境变量所包含的目录。
  3. Python标准库的安装目录。
  4. 第三方库的安装目录(如 site-packages)。

如果你的自定义模块不在这些路径下,你需要手动将其添加到 sys.path 中,或者使用虚拟环境和包管理工具(如 pip)来正确安装。

5. 标准库模块简介

Python的强大之处在于其丰富的“电池已包含”(batteries included)的标准库。这里列举几个常用模块:

  • os: 提供与操作系统交互的函数(文件、目录、环境变量)。
  • sys: 提供对Python解释器和系统相关的访问。
  • math: 数学运算(三角函数、对数、常数等)。
  • datetime: 日期和时间处理。
  • json: JSON数据的编码和解码。
  • random: 生成随机数。
  • collections: 提供额外的数据结构(如 namedtupledequeCounter)。
  • itertools: 提供用于创建高效迭代器的函数。
  • functools: 提供高阶函数和可调用对象的操作(如 lru_cachepartial)。
import datetime
now = datetime.datetime.now()
print(now.strftime("%Y-%m-%d %H:%M:%S"))

import json
data = {"name": "Alice", "age": 30}
json_string = json.dumps(data)
print(json_string)
parsed_data = json.loads(json_string)
print(parsed_data["name"])

综合案例:构建一个简易的“任务管理器”

让我们结合函数和模块,构建一个简单的命令行任务管理器。

项目结构:

task_manager/
├── __init__.py
├── task_manager.py   # 主程序逻辑
├── storage.py        # 数据持久化模块
└── utils.py          # 工具函数模块
# storage.py
"""处理任务数据的保存和加载。"""

import json
import os

TASKS_FILE = "tasks.json"

def load_tasks():
    """从文件加载任务列表。如果文件不存在,则返回空列表。"""
    if os.path.exists(TASKS_FILE):
        try:
            with open(TASKS_FILE, 'r', encoding='utf-8') as f:
                return json.load(f)
        except (json.JSONDecodeError, IOError) as e:
            print(f"加载任务失败: {e}")
            return []
    return []

def save_tasks(tasks):
    """将任务列表保存到文件。"""
    try:
        with open(TASKS_FILE, 'w', encoding='utf-8') as f:
            json.dump(tasks, f, ensure_ascii=False, indent=2)
        print("任务已保存。")
    except IOError as e:
        print(f"保存任务失败: {e}")
# utils.py
"""通用工具函数。"""

from datetime import datetime

def get_current_time_str():
    """获取格式化的当前时间字符串。"""
    return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

def validate_task_input(description):
    """验证任务描述是否有效。"""
    if not description or description.strip() == "":
        return False, "任务描述不能为空。"
    if len(description.strip()) > 100:
        return False, "任务描述不能超过100个字符。"
    return True, ""
# task_manager.py
"""任务管理器主程序。"""

from storage import load_tasks, save_tasks
from utils import get_current_time_str, validate_task_input

def display_menu():
    """显示菜单选项。"""
    print("\n=== 任务管理器 ===")
    print("1. 查看所有任务")
    print("2. 添加新任务")
    print("3. 标记任务完成")
    print("4. 删除任务")
    print("5. 退出")
    print("=" * 20)

def show_tasks(tasks):
    """展示所有任务。"""
    if not tasks:
        print("暂无任务。")
        return
    print("\n当前任务列表:")
    for idx, task in enumerate(tasks, start=1):
        status = "✓" if task['completed'] else "○"
        print(f"{idx}. [{status}] {task['description']} "
              f"(创建于: {task['created_at']})")

def add_task(tasks):
    """添加一个新任务。"""
    description = input("请输入任务描述: ").strip()
    is_valid, message = validate_task_input(description)
    if not is_valid:
        print(f"输入无效: {message}")
        return
    new_task = {
        "description": description,
        "completed": False,
        "created_at": get_current_time_str()
    }
    tasks.append(new_task)
    print("任务添加成功!")

def complete_task(tasks):
    """标记一个任务为完成。"""
    show_tasks(tasks)
    if not tasks:
        return
    try:
        choice = int(input("请输入要完成的任务编号: ")) - 1
        if 0 <= choice < len(tasks):
            if tasks[choice]['completed']:
                print("该任务已完成。")
            else:
                tasks[choice]['completed'] = True
                tasks[choice]['completed_at'] = get_current_time_str()
                print("任务已完成!")
        else:
            print("无效的编号!")
    except ValueError:
        print("请输入一个有效的数字!")

def delete_task(tasks):
    """删除一个任务。"""
    show_tasks(tasks)
    if not tasks:
        return
    try:
        choice = int(input("请输入要删除的任务编号: ")) - 1
        if 0 <= choice < len(tasks):
            removed_task = tasks.pop(choice)
            print(f"已删除任务: {removed_task['description']}")
        else:
            print("无效的编号!")
    except ValueError:
        print("请输入一个有效的数字!")

def main():
    """主函数。"""
    tasks = load_tasks()  # 启动时加载任务
    while True:
        display_menu()
        choice = input("请选择 (1-5): ").strip()
        if choice == '1':
            show_tasks(tasks)
        elif choice == '2':
            add_task(tasks)
        elif choice == '3':
            complete_task(tasks)
        elif choice == '4':
            delete_task(tasks)
        elif choice == '5':
            save_tasks(tasks)  # 退出前保存任务
            print("再见!")
            break
        else:
            print("无效选择,请重新输入。")

if __name__ == "__main__":
    main()
  • 函数是将代码逻辑封装起来的最小单元,它让代码可复用、可测试。
  • 模块是将相关函数、类和变量组织在一个文件中的单元,它让代码可组织、可分发。
  • 是将多个模块组织在目录结构中的单元,它让大型项目结构清晰。
  • 熟练掌握参数、作用域、装饰器、*args/**kwargs等高级特性,能让你写出更灵活、更强大的函数。
  • 理解 __name__ == "__main__" 模式,是编写健壮模块的基础。
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐