python动态设置非实例类属性

标签 python attributes metaprogramming

我正在尝试动态添加类属性,但不是在实例级别。例如。我可以手动做什么:

class Foo(object):
    a = 1
    b = 2
    c = 3

我希望能够:

class Foo(object):
    dct = {'a' : 1, 'b' : 2, 'c' : 3}
    for key, val in dct.items():
        <update the Foo namespace here>

我希望能够在不从类外部调用类(因此它是可移植的)或没有额外的类/装饰器的情况下执行此操作。这可能吗?

最佳答案

从您的示例代码来看,您想在创建类的同时执行此操作。在这种情况下,假设您使用的是 CPython,则可以使用 locals()

class Foo(object):
    locals().update(a=1, b=2, c=3)

这是有效的,因为在定义类时,locals() 引用类命名空间。它是特定于实现的行为,可能不适用于更高版本的 Python 或替代实现。

下面显示了一个使用类工厂的不太脏的版本。基本思想是通过 type() 构造函数将您的字典转换为类,然后将其用作新类的基类。为了方便用最少的语法定义属性,我使用了 ** 约定来接受属性。

def dicty(*bases, **attrs):
    if not bases:
        bases = (object,)
    return type("<from dict>", bases, attrs)

class Foo(dicty(a=1, b=2, c=3)):
    pass

# if you already have the dict, use unpacking

dct = dict(a=1, b=2, c=3)

class Foo(dicty(**dct)):
    pass

这实际上只是您自己调用 type() 的语法糖。这很好用,例如:

 class Foo(type("<none>", (object,), dict(a=1, b=2, c=3))):
     pass

关于python动态设置非实例类属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8490737/

相关文章:

python - 如何跨子模块导入

python - 在字典上映射

Python:绑定(bind)套接字: "Address already in use"

python - Pandas 在 groupby 对象上使用 groupby

android - 如何从字符串数组中提取名称属性?

metaprogramming - 元编程到底是什么?

python - 检查类名(字符串)是否用于 Python 中的某个类

python - 限制 Python 类中属性的可能值

python - 为什么它说我没有直肠

c++ - 比枚举好