You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

继承Langchain类时super().__init__及自定义属性添加异常问题

问题:LangChain继承Pydantic模型时添加自定义属性触发ValueError

初始可运行代码

以下代码可以正常运行:

from langchain_openai import ChatOpenAI

class LLM:
    def __init__(self, model_name):
        super().__init__(model_name=model_name)
        self.model_name = model_name  

class OpenAILLM(LLM, ChatOpenAI):
    def __init__(self, model_name):
        super().__init__(model_name=model_name)
        self.model_name = model_name

添加自定义属性后报错

当在OpenAILLM的__init__中添加自定义属性var时,创建对象失败:

from langchain_openai import ChatOpenAI

class LLM:
    def __init__(self, model_name):
        super().__init__(model_name=model_name)
        self.model_name = model_name  

class OpenAILLM(LLM, ChatOpenAI):
    def __init__(self, model_name):
        super().__init__(model_name=model_name)
        self.model_name = model_name
        self.var = 'var'

报错信息:

ValueError: "OpenAILLM" object has no field "var"

尝试类变量后的问题

将var声明为LLM的类变量后,get_var方法可以正常工作,但set_var方法触发相同错误:

from langchain_openai import ChatOpenAI

class LLM():
    var = 1
    def __init__(self, model_name):
        super().__init__(model_name=model_name)
        self.model_name = model_name  

class OpenAILLM(LLM, ChatOpenAI):
    def __init__(self, model_name):
        super().__init__(model_name=model_name)
        self.model_name = model_name
    def get_var(self):
        return self.var
    def set_var(self, var):
        print('self var', self.var)
        self.var = var
        return True

方法解析顺序(MRO)

OpenAILLM的MRO如下:

(__main__.OpenAILLM,
 __main__.LLM,
 langchain_openai.chat_models.base.ChatOpenAI,
 langchain_core.language_models.chat_models.BaseChatModel,
 langchain_core.language_models.base.BaseLanguageModel,
 langchain_core.runnables.base.RunnableSerializable,
 langchain_core.load.serializable.Serializable,
 pydantic.v1.main.BaseModel,
 pydantic.v1.utils.Representation,
 langchain_core.runnables.base.Runnable,
 typing.Generic,
 abc.ABC,
 object)

原因分析

从MRO可以看到,OpenAILLM间接继承了Pydantic v1的BaseModel。Pydantic v1的BaseModel默认会严格校验实例属性,不允许添加未在类中声明的字段。直接赋值self.var时,Pydantic会拦截并报错,因为var不是模型定义的字段。

解决方案

方案1:在子类中声明自定义字段

在OpenAILLM类中显式声明var字段,符合Pydantic的规范:

from langchain_openai import ChatOpenAI
from pydantic.v1 import Field

class LLM:
    def __init__(self, model_name):
        super().__init__(model_name=model_name)
        self.model_name = model_name  

class OpenAILLM(LLM, ChatOpenAI):
    var: str = Field(default='var')  # 声明字段,可设置默认值
    def __init__(self, model_name):
        super().__init__(model_name=model_name)
        self.model_name = model_name

方案2:允许额外字段

通过设置Extra.allow,让Pydantic允许添加未声明的字段:

from langchain_openai import ChatOpenAI
from pydantic.v1 import Extra

class LLM:
    def __init__(self, model_name):
        super().__init__(model_name=model_name)
        self.model_name = model_name  

class OpenAILLM(LLM, ChatOpenAI):
    class Config:
        extra = Extra.allow  # 允许额外字段
    def __init__(self, model_name):
        super().__init__(model_name=model_name)
        self.model_name = model_name
        self.var = 'var'

方案3:使用对象的__dict__赋值(不推荐)

绕过Pydantic的属性校验,直接修改__dict__,但可能破坏Pydantic的模型一致性:

from langchain_openai import ChatOpenAI

class LLM:
    def __init__(self, model_name):
        super().__init__(model_name=model_name)
        self.model_name = model_name  

class OpenAILLM(LLM, ChatOpenAI):
    def __init__(self, model_name):
        super().__init__(model_name=model_name)
        self.model_name = model_name
        self.__dict__['var'] = 'var'  # 直接修改__dict__

内容的提问来源于stack exchange,提问作者Yadnesh Salvi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 13:45:21