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

如何在Python类定义时动态设置类变量?

问题:在类定义阶段动态设置类变量

我想创建这样的类:

class Foo:
    hello = "world"
    goodbye = "moon"

但类中的变量是动态提供的,比如:

attrs = [("hello", "world"), ("goodbye", "moon")]

def create_class(attrs):
    class Foo:
        # 在这里插入动态属性
        pass
create_class(attrs)

我需要在类定义时就设置这些类变量,而非创建类后用setattr添加。我觉得可以借助__build_class__实现,但自己搞不定,求可行方法。


可行解决方案

方法1:直接用type()动态生成类

Python里类本身就是type的实例,直接调用type就能生成类,把属性字典传进去就行,这是最简洁的方式:

attrs = [("hello", "world"), ("goodbye", "moon")]

def create_class(attrs):
    attr_dict = dict(attrs)
    # 参数分别是:类名、父类元组、属性字典
    return type("Foo", (), attr_dict)

# 生成类并使用
Foo = create_class(attrs)
print(Foo.hello)  # 输出: world
print(Foo.goodbye)  # 输出: moon

方法2:用exec模拟手动定义类的过程

这种方式会动态生成类定义的代码字符串,然后执行它,完全和手动写类的效果一致,属性在定义阶段就存在于类的命名空间中:

attrs = [("hello", "world"), ("goodbye", "moon")]

def create_class(attrs):
    # 把属性转换成类内的赋值语句
    attr_assignments = "\n    ".join([f"{name} = {repr(value)}" for name, value in attrs])
    # 拼接完整的类定义代码
    class_def = f"""
class Foo:
    {attr_assignments}
"""
    # 执行代码,获取类对象
    local_ns = {}
    exec(class_def, globals(), local_ns)
    return local_ns["Foo"]

Foo = create_class(attrs)
print(Foo.hello)  # 输出: world

方法3:借助__build_class__钩子(进阶用法)

__build_class__是Python创建类的底层钩子,可以重写它来注入属性。不过这种方式本质还是在类创建后添加,但可以封装成定义阶段的逻辑:

attrs = [("hello", "world"), ("goodbye", "moon")]

def create_class(attrs):
    import builtins
    # 保存原生的构建函数
    original_build = builtins.__build_class__
    
    def custom_build(func, cls_name, *bases, **kwargs):
        # 先创建类
        cls = original_build(func, cls_name, *bases, **kwargs)
        # 注入动态属性
        for name, val in attrs:
            setattr(cls, name, val)
        return cls
    
    # 替换全局钩子
    builtins.__build_class__ = custom_build
    
    try:
        # 此时定义类会走自定义的构建逻辑
        class Foo:
            pass
    finally:
        # 恢复原生钩子,避免影响其他代码
        builtins.__build_class__ = original_build
    
    return Foo

Foo = create_class(attrs)
print(Foo.hello)  # 输出: world

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 04:00:09