深入剖析 Python 的 MRO 规则:从 C3 线性化到实战踩坑

1. 引言:为什么需要 MRO

在 Python 中,一个类可以同时继承多个父类,这就是所谓的多重继承。当子类调用某个方法时,如果这个方法在多个父类中都存在,Python 到底该用哪一个?

python 复制代码
class A:
    def hello(self):
        print("A.hello")

class B:
    def hello(self):
        print("B.hello")

class C(A, B):
    pass

C().hello()  # 输出什么?

答案是 A.hello。这个"选择顺序"就是 MRO(Method Resolution Order,方法解析顺序)。

MRO 决定了三件事:

  • 属性查找顺序 :obj.attr 时按什么顺序在类及其父类中查找;
  • 方法调用顺序 :super() 到底调用的是谁;
  • 多继承的合法性:某些继承结构 Python 会直接拒绝创建类。

理解 MRO,是写出可维护多重继承代码的前提,也是面试中高频考察的知识点。

2. MRO 的直观理解

2.1 一个简单的多继承例子

python 复制代码
class A:
    def who(self):
        print("A")

class B(A):
    def who(self):
        print("B")

class C(A):
    def who(self):
        print("C")

class D(B, C):
    pass

print(D.__mro__)

输出:

text 复制代码
(<class 'D'>, <class 'B'>, <class 'C'>, <class 'A'>, <class 'object'>)

可以看到,D 的查找顺序是 D → B → C → A → object。这就是一个典型的菱形继承结构:
#mermaid-svg-5Epmj2SaoMpI5fdr{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5Epmj2SaoMpI5fdr .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5Epmj2SaoMpI5fdr .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5Epmj2SaoMpI5fdr .error-icon{fill:#552222;}#mermaid-svg-5Epmj2SaoMpI5fdr .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5Epmj2SaoMpI5fdr .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5Epmj2SaoMpI5fdr .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5Epmj2SaoMpI5fdr .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5Epmj2SaoMpI5fdr .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5Epmj2SaoMpI5fdr .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5Epmj2SaoMpI5fdr .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5Epmj2SaoMpI5fdr .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5Epmj2SaoMpI5fdr .marker.cross{stroke:#333333;}#mermaid-svg-5Epmj2SaoMpI5fdr svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5Epmj2SaoMpI5fdr p{margin:0;}#mermaid-svg-5Epmj2SaoMpI5fdr .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5Epmj2SaoMpI5fdr .cluster-label text{fill:#333;}#mermaid-svg-5Epmj2SaoMpI5fdr .cluster-label span{color:#333;}#mermaid-svg-5Epmj2SaoMpI5fdr .cluster-label span p{background-color:transparent;}#mermaid-svg-5Epmj2SaoMpI5fdr .label text,#mermaid-svg-5Epmj2SaoMpI5fdr span{fill:#333;color:#333;}#mermaid-svg-5Epmj2SaoMpI5fdr .node rect,#mermaid-svg-5Epmj2SaoMpI5fdr .node circle,#mermaid-svg-5Epmj2SaoMpI5fdr .node ellipse,#mermaid-svg-5Epmj2SaoMpI5fdr .node polygon,#mermaid-svg-5Epmj2SaoMpI5fdr .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5Epmj2SaoMpI5fdr .rough-node .label text,#mermaid-svg-5Epmj2SaoMpI5fdr .node .label text,#mermaid-svg-5Epmj2SaoMpI5fdr .image-shape .label,#mermaid-svg-5Epmj2SaoMpI5fdr .icon-shape .label{text-anchor:middle;}#mermaid-svg-5Epmj2SaoMpI5fdr .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5Epmj2SaoMpI5fdr .rough-node .label,#mermaid-svg-5Epmj2SaoMpI5fdr .node .label,#mermaid-svg-5Epmj2SaoMpI5fdr .image-shape .label,#mermaid-svg-5Epmj2SaoMpI5fdr .icon-shape .label{text-align:center;}#mermaid-svg-5Epmj2SaoMpI5fdr .node.clickable{cursor:pointer;}#mermaid-svg-5Epmj2SaoMpI5fdr .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5Epmj2SaoMpI5fdr .arrowheadPath{fill:#333333;}#mermaid-svg-5Epmj2SaoMpI5fdr .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5Epmj2SaoMpI5fdr .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5Epmj2SaoMpI5fdr .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5Epmj2SaoMpI5fdr .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5Epmj2SaoMpI5fdr .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5Epmj2SaoMpI5fdr .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5Epmj2SaoMpI5fdr .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5Epmj2SaoMpI5fdr .cluster text{fill:#333;}#mermaid-svg-5Epmj2SaoMpI5fdr .cluster span{color:#333;}#mermaid-svg-5Epmj2SaoMpI5fdr div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5Epmj2SaoMpI5fdr .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5Epmj2SaoMpI5fdr rect.text{fill:none;stroke-width:0;}#mermaid-svg-5Epmj2SaoMpI5fdr .icon-shape,#mermaid-svg-5Epmj2SaoMpI5fdr .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5Epmj2SaoMpI5fdr .icon-shape p,#mermaid-svg-5Epmj2SaoMpI5fdr .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5Epmj2SaoMpI5fdr .icon-shape .label rect,#mermaid-svg-5Epmj2SaoMpI5fdr .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5Epmj2SaoMpI5fdr .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5Epmj2SaoMpI5fdr .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5Epmj2SaoMpI5fdr :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} A
B
C
D

2.2 两个核心约束

MRO 并不是随便排的,它必须同时满足两个约束:

  1. 局部优先顺序 :子类永远排在父类前面;在 class D(B, C) 中,B 必须排在 C 前面。
  2. 单调性:如果某个类在 MRO 中排在另一个类前面,那么在所有父类的 MRO 中也要保持这个相对顺序。

正是这两条约束,让 Python 2.3 之后采用了 C3 线性化算法。

3. C3 线性化算法详解

3.1 算法定义

C3 算法用递归方式定义类 C 的 MRO:

text 复制代码
L[C] = C + merge(L[B1], L[B2], ..., L[Bn], [B1, B2, ..., Bn])

其中 B1...Bn 是 C 的直接父类,merge 是一个特殊的合并操作。

merge 的规则是:

  • 依次取出列表的第一个元素作为候选;
  • 如果该候选没有出现在其他任何列表的尾部(即不是别人的"后继"),则把它取出,并从所有列表中删除;
  • 如果候选出现在某个列表的尾部,则跳过,看下一个列表的第一个元素;
  • 重复直到所有列表为空;若无法继续,说明继承关系存在冲突,抛出 TypeError。

3.2 手动推演一个例子

还是上面的菱形继承:

text 复制代码
L[A] = [A, object]
L[B] = [B] + merge(L[A], [A]) = [B, A, object]
L[C] = [C] + merge(L[A], [A]) = [C, A, object]
L[D] = [D] + merge(L[B], L[C], [B, C])

计算 merge([B, A, object], [C, A, object], [B, C]):

步骤 候选 是否在尾部 结果
1 B 否(B 只在 [B, C] 头部) 取出 B
2 A 是(在 [C, A, object] 尾部) 跳过
3 C 否 取出 C
4 A 否 取出 A
5 object 否 取出 object

最终:

text 复制代码
L[D] = [D, B, C, A, object]

与 D.__mro__ 的输出完全一致。

3.3 用代码验证

python 复制代码
def c3_mro(cls):
    """简化版 C3 线性化实现,用于验证"""
    bases = cls.__bases__
    if not bases:
        return [cls]
    seqs = [c3_mro(b) for b in bases] + [list(bases)]
    result = [cls]
    while True:
        seqs = [s for s in seqs if s]
        if not seqs:
            return result
        for seq in seqs:
            head = seq[0]
            if not any(head in s[1:] for s in seqs):
                break
        else:
            raise TypeError(f"Cannot create a consistent MRO for {cls}")
        result.append(head)
        for s in seqs:
            if s and s[0] is head:
                s.pop(0)

class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass

print(c3_mro(D) == list(D.__mro__))  # True

4. 冲突检测:什么时候会报错

C3 算法的一个重要作用是提前发现不合法的继承结构。

4.1 经典冲突案例

python 复制代码
class X: pass
class Y: pass
class A(X, Y): pass
class B(Y, X): pass

class C(A, B): pass  # TypeError

报错信息:

text 复制代码
TypeError: Cannot create a consistent method resolution order (MRO) for bases X, Y

原因分析:

  • A 要求 X 在 Y 前;
  • B 要求 Y 在 X 前;
  • C(A, B) 同时继承两者,无法同时满足,冲突。

4.2 冲突的本质

冲突的本质是偏序关系出现环 。C3 要求所有约束构成一个可拓扑排序的有向无环图,一旦出现 X < Y 和 Y < X 同时成立,就无法线性化。

4.3 如何排查

遇到这类报错时,可以逐个检查父类的 MRO:

python 复制代码
print(A.__mro__)
print(B.__mro__)

对比两者对共同祖先的相对顺序,通常就能定位冲突来源。实际工程中,这类问题多出现在混入(Mixin)组合场景,尤其是多个第三方库的基类被同时继承时。

5. super() 与 MRO 的协作机制

5.1 super() 不是"调用父类"

很多人误以为 super() 就是调用父类方法,实际上它调用的是 MRO 中当前类的下一个类。

python 复制代码
class A:
    def hello(self):
        print("A")

class B(A):
    def hello(self):
        print("B")
        super().hello()

class C(A):
    def hello(self):
        print("C")
        super().hello()

class D(B, C):
    def hello(self):
        print("D")
        super().hello()

D().hello()

输出:

text 复制代码
D
B
C
A

注意:B 中的 super().hello() 调用的是 C,而不是 A!因为 D 的 MRO 是 D → B → C → A,B 的下一个就是 C。

5.2 协作式多继承

这种机制被称为协作式多继承(cooperative multiple inheritance) :每个类只负责自己那部分逻辑,然后通过 super() 把控制权交给链上的下一个类。

python 复制代码
class LoggingMixin:
    def process(self, data):
        print(f"[LOG] processing {data}")
        return super().process(data)

class ValidationMixin:
    def process(self, data):
        if not data:
            raise ValueError("empty data")
        return super().process(data)

class Base:
    def process(self, data):
        return data.upper()

class Service(LoggingMixin, ValidationMixin, Base):
    pass

print(Service().process("hello"))

输出:

text 复制代码
[LOG] processing hello
HELLO

Service 的 MRO 是 Service → LoggingMixin → ValidationMixin → Base → object,super() 沿着这条链依次传递,每个 Mixin 只做自己的事。

5.3 关键细节:super() 的隐式参数

super() 在方法内部使用时,等价于 super(__class__, self),其中 __class__ 是定义该方法的类,而不是调用时的类。这正是协作式多继承能工作的根本原因。

python 复制代码
class B(A):
    def hello(self):
        # 这里的 super() 等价于 super(B, self)
        # 即使 self 是 D 的实例,也从 B 之后开始查找
        super().hello()

6. 实战中的常见陷阱

6.1 忘记调用 super()

python 复制代码
class Base:
    def __init__(self):
        self.value = 1

class Mixin:
    def __init__(self):
        self.extra = 2
        # 忘记 super().__init__()

class Child(Mixin, Base):
    pass

c = Child()
print(hasattr(c, "value"))  # False

Mixin.__init__ 没有调用 super().__init__(),导致 Base.__init__ 从未执行。协作式多继承要求链上每个类都调用 super()。

6.2 参数传递不一致

python 复制代码
class A:
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

class B:
    def __init__(self, name, **kwargs):
        self.name = name
        super().__init__(**kwargs)

class C(A, B):
    pass

C(name="test")  # 正常工作

推荐所有参与协作的类都使用 **kwargs 透传,避免参数在链上丢失。

6.3 直接调用父类方法破坏 MRO

python 复制代码
class B(A):
    def hello(self):
        A.hello(self)  # 硬编码,绕过了 MRO

这种写法在单继承下没问题,但在多继承中会重复调用 或跳过某些类 ,破坏协作链。应始终使用 super()。

6.4 混入类的顺序影响行为

python 复制代码
class Service(LoggingMixin, ValidationMixin, Base): ...
class Service2(ValidationMixin, LoggingMixin, Base): ...

两者的 MRO 不同,process 的执行顺序也不同。Mixin 的书写顺序就是执行顺序,需要根据业务语义谨慎排列。

7. 查看与分析 MRO 的工具

7.1 内置属性

python 复制代码
class D(B, C): pass

print(D.__mro__)      # 元组形式
print(D.mro())        # 列表形式,可被子类重写
print(D.__bases__)    # 直接父类

7.2 可视化 MRO

python 复制代码
def print_mro(cls, indent=0):
    print("  " * indent + cls.__name__)
    for base in cls.__bases__:
        print_mro(base, indent + 1)

class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass

print_mro(D)

输出:

text 复制代码
D
  B
    A
  C
    A

7.3 用 mermaid 画出继承与 MRO 的关系

#mermaid-svg-5MzbT0U1Qs7hWbQP{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5MzbT0U1Qs7hWbQP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5MzbT0U1Qs7hWbQP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5MzbT0U1Qs7hWbQP .error-icon{fill:#552222;}#mermaid-svg-5MzbT0U1Qs7hWbQP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5MzbT0U1Qs7hWbQP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5MzbT0U1Qs7hWbQP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5MzbT0U1Qs7hWbQP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5MzbT0U1Qs7hWbQP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5MzbT0U1Qs7hWbQP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5MzbT0U1Qs7hWbQP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5MzbT0U1Qs7hWbQP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5MzbT0U1Qs7hWbQP .marker.cross{stroke:#333333;}#mermaid-svg-5MzbT0U1Qs7hWbQP svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5MzbT0U1Qs7hWbQP p{margin:0;}#mermaid-svg-5MzbT0U1Qs7hWbQP .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5MzbT0U1Qs7hWbQP .cluster-label text{fill:#333;}#mermaid-svg-5MzbT0U1Qs7hWbQP .cluster-label span{color:#333;}#mermaid-svg-5MzbT0U1Qs7hWbQP .cluster-label span p{background-color:transparent;}#mermaid-svg-5MzbT0U1Qs7hWbQP .label text,#mermaid-svg-5MzbT0U1Qs7hWbQP span{fill:#333;color:#333;}#mermaid-svg-5MzbT0U1Qs7hWbQP .node rect,#mermaid-svg-5MzbT0U1Qs7hWbQP .node circle,#mermaid-svg-5MzbT0U1Qs7hWbQP .node ellipse,#mermaid-svg-5MzbT0U1Qs7hWbQP .node polygon,#mermaid-svg-5MzbT0U1Qs7hWbQP .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5MzbT0U1Qs7hWbQP .rough-node .label text,#mermaid-svg-5MzbT0U1Qs7hWbQP .node .label text,#mermaid-svg-5MzbT0U1Qs7hWbQP .image-shape .label,#mermaid-svg-5MzbT0U1Qs7hWbQP .icon-shape .label{text-anchor:middle;}#mermaid-svg-5MzbT0U1Qs7hWbQP .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5MzbT0U1Qs7hWbQP .rough-node .label,#mermaid-svg-5MzbT0U1Qs7hWbQP .node .label,#mermaid-svg-5MzbT0U1Qs7hWbQP .image-shape .label,#mermaid-svg-5MzbT0U1Qs7hWbQP .icon-shape .label{text-align:center;}#mermaid-svg-5MzbT0U1Qs7hWbQP .node.clickable{cursor:pointer;}#mermaid-svg-5MzbT0U1Qs7hWbQP .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5MzbT0U1Qs7hWbQP .arrowheadPath{fill:#333333;}#mermaid-svg-5MzbT0U1Qs7hWbQP .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5MzbT0U1Qs7hWbQP .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5MzbT0U1Qs7hWbQP .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5MzbT0U1Qs7hWbQP .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5MzbT0U1Qs7hWbQP .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5MzbT0U1Qs7hWbQP .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5MzbT0U1Qs7hWbQP .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5MzbT0U1Qs7hWbQP .cluster text{fill:#333;}#mermaid-svg-5MzbT0U1Qs7hWbQP .cluster span{color:#333;}#mermaid-svg-5MzbT0U1Qs7hWbQP div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5MzbT0U1Qs7hWbQP .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5MzbT0U1Qs7hWbQP rect.text{fill:none;stroke-width:0;}#mermaid-svg-5MzbT0U1Qs7hWbQP .icon-shape,#mermaid-svg-5MzbT0U1Qs7hWbQP .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5MzbT0U1Qs7hWbQP .icon-shape p,#mermaid-svg-5MzbT0U1Qs7hWbQP .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5MzbT0U1Qs7hWbQP .icon-shape .label rect,#mermaid-svg-5MzbT0U1Qs7hWbQP .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5MzbT0U1Qs7hWbQP .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5MzbT0U1Qs7hWbQP .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5MzbT0U1Qs7hWbQP :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} MRO 顺序
D
B
C
A
object
继承关系
D
B
C
A

8. 总结

要点 说明
MRO 定义 方法/属性的查找顺序
算法 C3 线性化,Python 2.3 起采用
核心约束 子类优先、单调性
冲突检测 偏序成环时抛 TypeError
super() 语义 调用 MRO 中当前类的下一个类
协作式多继承 链上每个类都调用 super() 并透传参数
常见陷阱 忘记 super、参数不一致、硬编码父类调用

一句话总结:MRO 是 Python 多重继承的"交通规则",C3 算法保证了这条规则的一致性和可预测性,而 super() 则是沿着这条规则行驶的车辆。

掌握 MRO,你就能放心地使用 Mixin 组合、理解框架源码中的继承结构,并在遇到 TypeError: Cannot create a consistent MRO 时快速定位问题。

相关推荐
123_不打狼1 小时前
Squidiff:基于条件扩散模型预测细胞发育与扰动响应
开发语言·python·squidiff
databook1 小时前
用Python DSL 写轻量数据质检工具
python·数据分析
郝学胜-神的一滴1 小时前
AI 编程智能体 17:四步搞定专属AI智能体
大数据·人工智能·python·神经网络·算法·langchain·强化学习
岁寒良木2 小时前
麒麟 V10 (x86_64) 离线/联网部署 Docker 26.1.4 与 MaxKB v2.10 LTS 实战指南
python·docker·kylin
瑞got2 小时前
java使用CountDownLatch做并行查询
java·开发语言
OxYGC2 小时前
[Web3] 的⛽ Gas 革命:五大协议群组如何终结“Gas 痛点
web3·1024程序员节·layer2·gas·erc-4337
Norna2 小时前
receive 取消了,TCP 为什么还在读:AnyIO 的一次背压修复
python
OxYGC2 小时前
[Web3] 去中心化基石 - BIP铁三角(BIP32/39/44)
web3·1024程序员节·钱包·bip32·bip44