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

如何从具体类的__init__获取默认参数到元类的__call__方法中?

获取元类__call__中类__init__的默认参数值

当调用类创建实例时,如果未显式传递带有默认值的参数,元类的__call__方法收到的kwargs是空字典——因为默认参数是在__init__方法执行时才被赋值的,而非在调用类阶段就传入。要在__call__中获取这些默认参数的值,可以通过Python的inspect模块解析__init__方法的参数签名来实现。

方法一:使用inspect.signature(推荐,支持复杂参数)

inspect.signature可以获取方法的完整参数结构,结合bind和apply_defaults方法能自动填充未传递参数的默认值:

import inspect

class Meta(type):
    def __call__(cls, *args, **kwargs):
        # 获取__init__方法的参数签名
        sig = inspect.signature(cls.__init__)
        # 绑定传入的位置参数和关键字参数
        bound_args = sig.bind(*args, **kwargs)
        # 为未传递的参数应用默认值
        bound_args.apply_defaults()
        
        print(cls)
        print(f"args = {args}")
        print(f"kwargs = {kwargs}")
        # 输出包含所有参数(含默认值)的字典,注意包含self参数
        print(f"full arguments with defaults: {bound_args.arguments}")
        
        return super().__call__(*args, **kwargs)


class Actual(metaclass=Meta):
    def __init__(self, value=1):
        print(f"value=P{value}")


a1 = Actual()
a2 = Actual(value=2)

运行输出:

<class '__main__.Actual'>
args = ()
kwargs = {}
full arguments with defaults: {'self': <__main__.Actual object at 0x...>, 'value': 1}
value=P1
<class '__main__.Actual'>
args = ()
kwargs = {'value': 2}
full arguments with defaults: {'self': <__main__.Actual object at 0x...>, 'value': 2}
value=P2

如果只需要用户定义的参数(排除self),可以从bound_args.arguments中过滤掉self键。

方法二:使用inspect.getfullargspec(适合简单参数场景)

对于结构简单的__init__方法,也可以用inspect.getfullargspec直接提取参数名和默认值,手动合并到kwargs中:

import inspect

class Meta(type):
    def __call__(cls, *args, **kwargs):
        argspec = inspect.getfullargspec(cls.__init__)
        # 提取除self外的参数名
        param_names = argspec.args[1:]
        # 获取默认参数值,若无默认参数则为空元组
        default_values = argspec.defaults or ()
        
        # 构建默认参数字典(参数名和默认值对应)
        default_kwargs = dict(zip(param_names[-len(default_values):], default_values))
        # 合并传入的kwargs和默认参数,传入的参数优先级更高
        full_kwargs = {**default_kwargs, **kwargs}
        
        print(cls)
        print(f"args = {args}")
        print(f"kwargs = {kwargs}")
        print(f"full kwargs with defaults: {full_kwargs}")
        
        return super().__call__(*args, **kwargs)

运行输出:

<class '__main__.Actual'>
args = ()
kwargs = {}
full kwargs with defaults: {'value': 1}
value=P1
<class '__main__.Actual'>
args = ()
kwargs = {'value': 2}
full kwargs with defaults: {'value': 2}
value=P2

这两种方法都能在元类的__call__方法中获取到__init__的默认参数值,根据参数复杂度选择即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 23:50:32