目录

  • Python“魔法方法”入门:从`__init__`到`__str__`
    • 1. 引言:什么是魔法方法?
      • 1.1 魔法方法的重要性
      • 1.2 一个简单的例子
    • 2. 构造与初始化方法
      • 2.1 `__new__` vs `__init__`
      • 2.2 `__init__`方法的深入理解
      • 2.3 `__del__`:析构方法
    • 3. 对象表示方法
      • 3.1 `__str__` vs `__repr__`
      • 3.2 何时使用哪种表示方法
    • 4. 比较运算魔法方法
      • 4.1 基本比较方法
      • 4.2 比较运算的数学原理
    • 5. 算术运算魔法方法
      • 5.1 基本算术运算
      • 5.2 算术运算的数学原理
    • 6. 类型转换魔法方法
      • 6.1 基本类型转换方法
    • 7. 容器类魔法方法
      • 7.1 实现一个自定义列表
    • 8. 完整示例:一个完整的数学向量类
      • 代码自查与说明
    • 9. 总结
      • 9.1 主要收获
      • 9.2 进一步学习

『宝藏代码胶囊开张啦!』—— 我的 CodeCapsule 来咯!✨
写代码不再头疼!我的新站点 CodeCapsule 主打一个 “白菜价”+“量身定制”!无论是卡脖子的毕设/课设/文献复现,需要灵光一现的算法改进,还是想给项目加个“外挂”,这里都有便宜又好用的代码方案等你发现!低成本,高适配,助你轻松通关!速来围观 👉 CodeCapsule官网

Python“魔法方法”入门:从__init____str__

1. 引言:什么是魔法方法?

在Python中,有一类特殊的方法,它们以双下划线开头和结尾,被称为魔法方法(Magic Methods)或双下方法(Dunder Methods)。这些方法不是让我们直接调用的,而是由Python解释器在特定时机自动调用。

1.1 魔法方法的重要性

魔法方法是Python面向对象编程的核心。它们使得我们可以:

  • 自定义对象的初始化过程
  • 定义对象如何被打印和显示
  • 重载运算符(如+、-、*、/等)
  • 让对象支持上下文管理器(with语句)
  • 实现自定义的容器行为

1.2 一个简单的例子

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __str__(self):
        return f"Person(name='{self.name}', age={self.age})"

# 使用示例
person = Person("Alice", 25)
print(person)  # 自动调用__str__方法

输出:

Person(name='Alice', age=25)

2. 构造与初始化方法

2.1 __new__ vs __init__

很多人混淆这两个方法,但它们有明确的职责分工:

class Example:
    def __new__(cls, *args, **kwargs):
        """创建实例,返回实例对象"""
        print("__new__被调用")
        instance = super().__new__(cls)
        return instance
    
    def __init__(self, value):
        """初始化实例,设置初始状态"""
        print("__init__被调用")
        self.value = value

# 测试
obj = Example(10)

输出:

__new__被调用
__init__被调用

关键区别

  • __new__:类方法,负责创建实例
  • __init__:实例方法,负责初始化实例

2.2 __init__方法的深入理解

__init__是最常用的魔法方法,用于对象的初始化:

class Vector:
    def __init__(self, x, y, z=0):
        """
        初始化三维向量
        
        参数:
            x: x坐标
            y: y坐标  
            z: z坐标(默认为0)
        """
        self.x = x
        self.y = y
        self.z = z
        self.magnitude = (x**2 + y**2 + z**2) ** 0.5

# 使用示例
v1 = Vector(3, 4)      # 二维向量,z默认为0
v2 = Vector(1, 2, 3)   # 三维向量

print(f"v1: ({v1.x}, {v1.y}, {v1.z}), 模长: {v1.magnitude:.2f}")
print(f"v2: ({v2.x}, {v2.y}, {v2.z}), 模长: {v2.magnitude:.2f}")

2.3 __del__:析构方法

当对象被垃圾回收时调用:

class Resource:
    def __init__(self, name):
        self.name = name
        print(f"资源 {self.name} 被创建")
    
    def __del__(self):
        print(f"资源 {self.name} 被释放")

def test_del():
    res = Resource("临时资源")
    # 函数结束时,res超出作用域,触发__del__

test_del()

3. 对象表示方法

3.1 __str__ vs __repr__

这两个方法都用于对象的字符串表示,但用途不同:

class Student:
    def __init__(self, name, student_id, grades=None):
        self.name = name
        self.student_id = student_id
        self.grades = grades or []
    
    def __str__(self):
        """用户友好的字符串表示"""
        avg_grade = sum(self.grades) / len(self.grades) if self.grades else 0
        return f"学生{self.name}(学号:{self.student_id}), 平均分:{avg_grade:.1f}"
    
    def __repr__(self):
        """开发者友好的字符串表示,应该能够用于重新创建对象"""
        return f"Student('{self.name}', '{self.student_id}', {self.grades})"
    
    def add_grade(self, grade):
        """添加成绩"""
        self.grades.append(grade)

# 测试
student = Student("张三", "2023001", [85, 92, 78])
student.add_grade(88)

print(str(student))    # 调用__str__
print(repr(student))   # 调用__repr__

# 在交互式环境中,直接输入变量名会调用__repr__

输出:

学生张三(学号:2023001), 平均分:85.8
Student('张三', '2023001', [85, 92, 78, 88])

3.2 何时使用哪种表示方法

下面的流程图说明了Python如何选择使用__str__还是__repr__

graph TD
    A[需要对象的字符串表示] --> B{使用场景是什么?}
    B -->|print(obj) <br> str(obj) <br> f-string格式化| C[优先使用 __str__]
    B -->|交互式环境直接输入obj <br> repr(obj) <br> 容器中显示| D[使用 __repr__]
    C --> E{__str__ 已定义?}
    D --> F{__repr__ 已定义?}
    E -->|是| G[调用 __str__]
    E -->|否| H[回退到 __repr__]
    F -->|是| I[调用 __repr__]
    F -->|否| J[使用默认对象表示<br>如&lt;__main__.Student object&gt;]
    G --> K[返回友好字符串]
    H --> I
    I --> L[返回精确字符串]

4. 比较运算魔法方法

Python允许我们重载比较运算符,让自定义对象支持比较操作。

4.1 基本比较方法

class Fraction:
    """分数类"""
    
    def __init__(self, numerator, denominator=1):
        if denominator == 0:
            raise ValueError("分母不能为零")
        
        # 简化分数
        gcd_val = self._gcd(abs(numerator), abs(denominator))
        self.numerator = numerator // gcd_val
        self.denominator = denominator // gcd_val
        
        # 确保分母为正
        if self.denominator < 0:
            self.numerator = -self.numerator
            self.denominator = -self.denominator
    
    def _gcd(self, a, b):
        """计算最大公约数"""
        while b:
            a, b = b, a % b
        return a
    
    def to_float(self):
        """转换为浮点数"""
        return self.numerator / self.denominator
    
    # 比较运算方法
    def __eq__(self, other):
        """等于 =="""
        if isinstance(other, Fraction):
            return (self.numerator == other.numerator and 
                   self.denominator == other.denominator)
        return self.to_float() == other
    
    def __lt__(self, other):
        """小于 <"""
        if isinstance(other, Fraction):
            return (self.numerator * other.denominator < 
                   other.numerator * self.denominator)
        return self.to_float() < other
    
    def __le__(self, other):
        """小于等于 <="""
        return self < other or self == other
    
    def __gt__(self, other):
        """大于 >"""
        return not self <= other
    
    def __ge__(self, other):
        """大于等于 >="""
        return not self < other
    
    def __ne__(self, other):
        """不等于 !="""
        return not self == other
    
    def __str__(self):
        if self.denominator == 1:
            return str(self.numerator)
        return f"{self.numerator}/{self.denominator}"
    
    def __repr__(self):
        return f"Fraction({self.numerator}, {self.denominator})"

# 测试比较运算
f1 = Fraction(1, 2)
f2 = Fraction(2, 4)  # 等于1/2
f3 = Fraction(3, 4)

print(f"{f1} == {f2}: {f1 == f2}")  # True
print(f"{f1} < {f3}: {f1 < f3}")    # True
print(f"{f3} > {f1}: {f3 > f1}")    # True
print(f"{f1} == 0.5: {f1 == 0.5}")  # True

4.2 比较运算的数学原理

当我们比较两个分数 a b \frac{a}{b} ba c d \frac{c}{d} dc 时:

  • 相等性比较 a b = c d    ⟺    a × d = b × c \frac{a}{b} = \frac{c}{d} \iff a \times d = b \times c ba=dca×d=b×c
  • 大小比较 a b < c d    ⟺    a × d < b × c \frac{a}{b} < \frac{c}{d} \iff a \times d < b \times c ba<dca×d<b×c(假设 b , d > 0 b, d > 0 b,d>0

这种方法避免了浮点数精度问题,直接使用整数运算进行比较。

5. 算术运算魔法方法

5.1 基本算术运算

让我们扩展Fraction类来支持算术运算:

class Fraction:
    # ... 之前的代码保持不变 ...
    
    # 算术运算方法
    def __add__(self, other):
        """加法 +"""
        if isinstance(other, Fraction):
            new_num = (self.numerator * other.denominator + 
                      other.numerator * self.denominator)
            new_den = self.denominator * other.denominator
            return Fraction(new_num, new_den)
        elif isinstance(other, (int, float)):
            return self + Fraction(other)
        return NotImplemented
    
    def __radd__(self, other):
        """右加法,处理 other + self 的情况"""
        return self + other
    
    def __sub__(self, other):
        """减法 -"""
        if isinstance(other, Fraction):
            new_num = (self.numerator * other.denominator - 
                      other.numerator * self.denominator)
            new_den = self.denominator * other.denominator
            return Fraction(new_num, new_den)
        elif isinstance(other, (int, float)):
            return self - Fraction(other)
        return NotImplemented
    
    def __rsub__(self, other):
        """右减法"""
        return Fraction(other) - self
    
    def __mul__(self, other):
        """乘法 *"""
        if isinstance(other, Fraction):
            return Fraction(self.numerator * other.numerator,
                           self.denominator * other.denominator)
        elif isinstance(other, (int, float)):
            return Fraction(self.numerator * other, self.denominator)
        return NotImplemented
    
    def __rmul__(self, other):
        """右乘法"""
        return self * other
    
    def __truediv__(self, other):
        """除法 /"""
        if isinstance(other, Fraction):
            return self * Fraction(other.denominator, other.numerator)
        elif isinstance(other, (int, float)):
            return self * Fraction(1, other)
        return NotImplemented
    
    def __rtruediv__(self, other):
        """右除法"""
        return Fraction(other) / self
    
    def __floordiv__(self, other):
        """整除 //"""
        result = self / other
        return Fraction(int(result.to_float()), 1)
    
    def __mod__(self, other):
        """取模 %"""
        if isinstance(other, Fraction):
            quotient = self // other
            return self - quotient * other
        return NotImplemented
    
    def __pow__(self, exponent):
        """幂运算 **"""
        if isinstance(exponent, int):
            return Fraction(self.numerator ** exponent, 
                           self.denominator ** exponent)
        return NotImplemented

# 测试算术运算
f1 = Fraction(1, 2)
f2 = Fraction(3, 4)

print(f"{f1} + {f2} = {f1 + f2}")      # 1/2 + 3/4 = 5/4
print(f"{f1} - {f2} = {f1 - f2}")      # 1/2 - 3/4 = -1/4
print(f"{f1} * {f2} = {f1 * f2}")      # 1/2 * 3/4 = 3/8
print(f"{f1} / {f2} = {f1 / f2}")      # 1/2 ÷ 3/4 = 2/3
print(f"{f1} ** 2 = {f1 ** 2}")        # (1/2)² = 1/4

# 测试反向运算
print(f"2 + {f1} = {2 + f1}")          # 2 + 1/2 = 5/2
print(f"3 * {f1} = {3 * f1}")          # 3 * 1/2 = 3/2

5.2 算术运算的数学原理

分数运算遵循标准的数学规则:

  • 加法 a b + c d = a d + b c b d \frac{a}{b} + \frac{c}{d} = \frac{ad + bc}{bd} ba+dc=bdad+bc
  • 减法 a b − c d = a d − b c b d \frac{a}{b} - \frac{c}{d} = \frac{ad - bc}{bd} badc=bdadbc
  • 乘法 a b × c d = a c b d \frac{a}{b} \times \frac{c}{d} = \frac{ac}{bd} ba×dc=bdac
  • 除法 a b ÷ c d = a b × d c = a d b c \frac{a}{b} \div \frac{c}{d} = \frac{a}{b} \times \frac{d}{c} = \frac{ad}{bc} ba÷dc=ba×cd=bcad

6. 类型转换魔法方法

6.1 基本类型转换方法

class SmartNumber:
    """智能数字类,支持各种类型转换"""
    
    def __init__(self, value):
        self.value = float(value)
    
    # 类型转换方法
    def __int__(self):
        """转换为整数"""
        return int(self.value)
    
    def __float__(self):
        """转换为浮点数"""
        return self.value
    
    def __bool__(self):
        """转换为布尔值"""
        return self.value != 0
    
    def __complex__(self):
        """转换为复数"""
        return complex(self.value, 0)
    
    # 数值表示方法
    def __str__(self):
        return f"SmartNumber({self.value})"
    
    def __repr__(self):
        return f"SmartNumber({self.value})"
    
    # 算术运算(简化版)
    def __add__(self, other):
        if isinstance(other, (int, float)):
            return SmartNumber(self.value + other)
        return NotImplemented

# 测试类型转换
num = SmartNumber(3.14)

print(f"整数: {int(num)}")           # 3
print(f"浮点数: {float(num)}")       # 3.14
print(f"布尔值: {bool(num)}")        # True
print(f"复数: {complex(num)}")       # (3.14+0j)
print(f"零值的布尔: {bool(SmartNumber(0))}")  # False

7. 容器类魔法方法

7.1 实现一个自定义列表

class StatisticsList:
    """统计列表,增强的列表类,支持统计功能"""
    
    def __init__(self, initial_data=None):
        self._data = list(initial_data) if initial_data else []
    
    # 基本容器方法
    def __getitem__(self, index):
        """支持索引访问"""
        return self._data[index]
    
    def __setitem__(self, index, value):
        """支持索引赋值"""
        self._data[index] = value
    
    def __delitem__(self, index):
        """支持删除元素"""
        del self._data[index]
    
    def __len__(self):
        """返回列表长度"""
        return len(self._data)
    
    def __contains__(self, item):
        """支持in操作符"""
        return item in self._data
    
    def __iter__(self):
        """支持迭代"""
        return iter(self._data)
    
    def append(self, item):
        """添加元素"""
        self._data.append(item)
    
    # 统计方法
    def mean(self):
        """计算平均值"""
        if not self._data:
            return 0
        return sum(self._data) / len(self._data)
    
    def median(self):
        """计算中位数"""
        if not self._data:
            return 0
        
        sorted_data = sorted(self._data)
        n = len(sorted_data)
        mid = n // 2
        
        if n % 2 == 0:
            return (sorted_data[mid-1] + sorted_data[mid]) / 2
        else:
            return sorted_data[mid]
    
    def mode(self):
        """计算众数"""
        if not self._data:
            return []
        
        from collections import Counter
        counter = Counter(self._data)
        max_count = max(counter.values())
        return [num for num, count in counter.items() if count == max_count]
    
    def variance(self):
        """计算方差"""
        if len(self._data) < 2:
            return 0
        
        mean_val = self.mean()
        return sum((x - mean_val) ** 2 for x in self._data) / (len(self._data) - 1)
    
    def std_dev(self):
        """计算标准差"""
        return self.variance() ** 0.5
    
    def __str__(self):
        return f"StatisticsList({self._data})"
    
    def __repr__(self):
        return f"StatisticsList({self._data})"

# 测试统计列表
stats_list = StatisticsList([1, 2, 2, 3, 4, 5, 5, 5])

print(f"列表: {stats_list}")
print(f"长度: {len(stats_list)}")
print(f"平均值: {stats_list.mean():.2f}")
print(f"中位数: {stats_list.median()}")
print(f"众数: {stats_list.mode()}")
print(f"方差: {stats_list.variance():.2f}")
print(f"标准差: {stats_list.std_dev():.2f}")

# 测试容器功能
print(f"包含3: {3 in stats_list}")
print(f"索引2的值: {stats_list[2]}")

8. 完整示例:一个完整的数学向量类

现在让我们将所有知识整合起来,创建一个功能完整的数学向量类:

import math
from numbers import Real

class Vector:
    """
    数学向量类,支持基本的向量运算
    实现二维和三维向量操作
    """
    
    def __init__(self, *components):
        """
        初始化向量
        
        参数:
            *components: 向量的分量,支持2D或3D向量
        """
        if not components:
            raise ValueError("向量必须至少有一个分量")
        
        if not all(isinstance(c, Real) for c in components):
            raise TypeError("向量分量必须是实数")
        
        self._components = tuple(float(c) for c in components)
        self._dim = len(components)
    
    @property
    def dim(self):
        """返回向量维度"""
        return self._dim
    
    @property
    def components(self):
        """返回向量分量(只读)"""
        return self._components
    
    @property
    def magnitude(self):
        """计算向量模长"""
        return math.sqrt(sum(x**2 for x in self._components))
    
    @property
    def unit_vector(self):
        """返回单位向量"""
        mag = self.magnitude
        if mag == 0:
            raise ValueError("零向量没有单位向量")
        return Vector(*(x / mag for x in self._components))
    
    # 表示方法
    def __str__(self):
        comp_str = ", ".join(f"{x:.2f}" for x in self._components)
        return f"Vector({comp_str})"
    
    def __repr__(self):
        comp_str = ", ".join(str(x) for x in self._components)
        return f"Vector({comp_str})"
    
    # 比较运算
    def __eq__(self, other):
        """向量相等性判断"""
        if not isinstance(other, Vector):
            return False
        return (self._dim == other._dim and 
                self._components == other._components)
    
    def __abs__(self):
        """返回向量的模长"""
        return self.magnitude
    
    # 算术运算
    def __add__(self, other):
        """向量加法"""
        if isinstance(other, Vector):
            if self._dim != other._dim:
                raise ValueError("向量维度必须相同才能相加")
            return Vector(*(a + b for a, b in zip(self._components, other._components)))
        return NotImplemented
    
    def __sub__(self, other):
        """向量减法"""
        if isinstance(other, Vector):
            if self._dim != other._dim:
                raise ValueError("向量维度必须相同才能相减")
            return Vector(*(a - b for a, b in zip(self._components, other._components)))
        return NotImplemented
    
    def __mul__(self, other):
        """向量数乘或点积"""
        if isinstance(other, Real):
            # 数乘
            return Vector(*(x * other for x in self._components))
        elif isinstance(other, Vector):
            # 点积
            if self._dim != other._dim:
                raise ValueError("向量维度必须相同才能计算点积")
            return sum(a * b for a, b in zip(self._components, other._components))
        return NotImplemented
    
    def __rmul__(self, other):
        """右数乘"""
        if isinstance(other, Real):
            return self * other
        return NotImplemented
    
    def __truediv__(self, other):
        """向量数除"""
        if isinstance(other, Real):
            if other == 0:
                raise ZeroDivisionError("不能除以零")
            return Vector(*(x / other for x in self._components))
        return NotImplemented
    
    def __matmul__(self, other):
        """向量叉积(使用@运算符)"""
        if isinstance(other, Vector):
            if self._dim != 3 or other._dim != 3:
                raise ValueError("叉积只支持三维向量")
            
            x1, y1, z1 = self._components
            x2, y2, z2 = other._components
            
            return Vector(
                y1 * z2 - z1 * y2,
                z1 * x2 - x1 * z2,
                x1 * y2 - y1 * x2
            )
        return NotImplemented
    
    def dot(self, other):
        """点积(方法形式)"""
        return self * other
    
    def cross(self, other):
        """叉积(方法形式)"""
        return self @ other
    
    def angle_between(self, other):
        """计算两向量夹角(弧度)"""
        if self.magnitude == 0 or other.magnitude == 0:
            raise ValueError("不能计算零向量的夹角")
        
        dot_product = self.dot(other)
        cos_theta = dot_product / (self.magnitude * other.magnitude)
        
        # 处理浮点数精度问题
        cos_theta = max(-1.0, min(1.0, cos_theta))
        return math.acos(cos_theta)
    
    def is_orthogonal(self, other, tolerance=1e-10):
        """判断两向量是否正交"""
        return abs(self.dot(other)) < tolerance
    
    def is_parallel(self, other, tolerance=1e-10):
        """判断两向量是否平行"""
        if self.magnitude == 0 or other.magnitude == 0:
            return True  # 零向量与任何向量平行
        
        cos_theta = abs(self.dot(other)) / (self.magnitude * other.magnitude)
        return abs(cos_theta - 1.0) < tolerance
    
    # 容器方法
    def __getitem__(self, index):
        """支持索引访问分量"""
        if index < 0 or index >= self._dim:
            raise IndexError("向量索引越界")
        return self._components[index]
    
    def __len__(self):
        """返回向量维度"""
        return self._dim
    
    def __iter__(self):
        """支持迭代"""
        return iter(self._components)

# 测试完整的向量类
def test_vector_class():
    """测试向量类的各种功能"""
    
    print("=== 向量类测试 ===\n")
    
    # 创建向量
    v1 = Vector(1, 2, 3)
    v2 = Vector(4, 5, 6)
    
    print(f"v1 = {v1}")
    print(f"v2 = {v2}")
    print(f"v1的维度: {v1.dim}")
    print(f"v1的模长: {v1.magnitude:.2f}")
    print(f"v1的单位向量: {v1.unit_vector}")
    
    # 向量运算
    print(f"\n=== 向量运算 ===")
    print(f"v1 + v2 = {v1 + v2}")
    print(f"v2 - v1 = {v2 - v1}")
    print(f"v1 * 2 = {v1 * 2}")
    print(f"3 * v2 = {3 * v2}")
    print(f"v1 / 2 = {v1 / 2}")
    
    # 点积和叉积
    print(f"\n=== 点积和叉积 ===")
    print(f"v1 · v2 = {v1.dot(v2):.2f}")
    print(f"v1 × v2 = {v1.cross(v2)}")
    
    # 向量关系
    print(f"\n=== 向量关系 ===")
    v3 = Vector(2, 4, 6)  # 与v1平行
    v4 = Vector(1, -0.5, 0)  # 与v1大致正交
    
    print(f"v1 == v2: {v1 == v2}")
    print(f"v1与v3平行: {v1.is_parallel(v3)}")
    print(f"v1与v4正交: {v1.is_orthogonal(v4)}")
    
    # 计算夹角
    angle_rad = v1.angle_between(v2)
    angle_deg = math.degrees(angle_rad)
    print(f"v1与v2的夹角: {angle_rad:.2f} 弧度 ({angle_deg:.1f} 度)")
    
    # 测试2D向量
    print(f"\n=== 2D向量测试 ===")
    v5 = Vector(3, 4)
    print(f"2D向量v5: {v5}")
    print(f"v5的模长: {v5.magnitude}")

if __name__ == "__main__":
    test_vector_class()

代码自查与说明

  1. 数学正确性

    • 向量运算遵循数学定义
    • 处理了边界情况(如零向量)
    • 使用适当的数值稳定性技巧
  2. 代码规范

    • 完整的文档字符串
    • 清晰的变量命名
    • 适当的错误处理
  3. 魔法方法覆盖

    • __init__: 对象初始化
    • __str__/__repr__: 字符串表示
    • 比较运算方法
    • 算术运算方法
    • 容器协议方法
  4. 功能完整性

    • 支持2D和3D向量
    • 实现所有基本向量运算
    • 提供高级数学功能

这个向量类展示了如何综合运用各种魔法方法来创建一个功能完整、接口自然的数学类。

9. 总结

通过本文的学习,我们深入了解了Python魔法方法的核心概念:

9.1 主要收获

  1. 魔法方法的作用:让自定义类具有内置类型一样的行为

  2. 常用魔法方法分类

    • 构造初始化:__init__, __new__, __del__
    • 对象表示:__str__, __repr__
    • 比较运算:__eq__, __lt__, 等
    • 算术运算:__add__, __sub__, __mul__, 等
    • 类型转换:__int__, __float__, __bool__
    • 容器协议:__getitem__, __setitem__, __len__
  3. 最佳实践

    • 始终返回NotImplemented而不是抛出TypeError
    • 实现反向运算方法(如__radd__
    • 区分__str____repr__的用途
    • 保持数学运算的准确性

9.2 进一步学习

要深入学习魔法方法,建议:

  1. 阅读Python官方文档的数据模型章节
  2. 研究标准库中类的实现(如collections模块)
  3. 实践实现更复杂的魔法方法,如上下文管理器(__enter__, __exit__

掌握魔法方法是成为Python高级程序员的重要一步,它们让代码更加Pythonic和优雅。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐