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

Python中使用__slots__字典实现属性初始化是否合法安全?

我在寻找便捷的slots初始化方法时,冒出了不知道算不算愚蠢、算不算错误的想法:如下所示将__slots__字典用于初始化用途。

注意:我此前曾将我的思路作为答案发布在相关问题下,但我认为单独提出新问题能获得更多反馈,因此创建了本问询。

希望大家能就以下这个“小技巧”给出说明、建议或是指出可能存在的问题:

class Slotted:

    __slots__ = {}

    def __new__(cls, *args, **kwargs):
        inst = super().__new__(cls)
        for key, value in inst.__slots__.items():
            setattr(inst, key, value)
        return inst

class Magic(Slotted):

    __slots__ = {
        "foo": True,
        "bar": 17
    }
magic = Magic()

print(f"magic.foo = {magic.foo}")
print(f"magic.bar = {magic.bar}")

运行输出:

magic.foo = True
magic.bar = 17

这么做是否合规、安全?存在什么缺陷或是潜在问题?


编辑:
在有开发者提到Python 3.8+中该写法的文档用途后,我对方案做了扩展,同时修正了进一步子类化的问题,不过现在代码变得稍长了一些:

class Slot(str):

    __slots__ = ["init"]

    def __new__(cls, init, doc=""):
        obj = str.__new__(cls, doc)
        obj.init = init
        return obj

    def __call__(self):
        return self.init

class Slotted:

    __slots__ = {}

    def __new__(cls, *args, **kwargs):
        obj = super().__new__(cls)
        for base in reversed(cls.__mro__[:-1]):
            if isinstance(base.__slots__, dict):
                for key, value in base.__slots__.items():
                    if isinstance(value, Slot):
                        setattr(obj, key, value())
                    else:
                        raise TypeError(
                            f'Value for slot "{key}" must'
                            f' be of type "{Slot.__name__}"'
                        )
        return obj
class Magic(Slotted):
    """This class is not so boring any more"""

    __slots__ = {
        "foo": Slot(2, doc="Some quite interesting integer"),
        "bar": Slot(3.1416, doc="Some very exciting float")
    }

help(Magic)
magic = Magic()
print(f"magic.__slots__ = {magic.__slots__}")
print(f"magic.foo = {magic.foo}")
print(f"magic.bar = {magic.bar}")

运行输出:

Help on class Magic in module __main__:

class Magic(Slotted)
 |  Magic(*args, **kwargs)
 |  
 |  This class is not so boring any more
 |  
 |  Method resolution order:
 |      Magic
 |      Slotted
 |      builtins.object
 |  
 |  Data descriptors defined here:
 |  
 |  bar
 |      Some very exciting float
 |  
 |  foo
 |      Some quite interesting integer
 |  
 |  ----------------------------------------------------------------------
 |  Static methods inherited from Slotted:
 |  
 |  __new__(cls, *args, **kwargs)
 |      Create and return a new object.  See help(type) for accurate signature.

magic.__slots__ = {'foo': 'Some quite interesting integer', 'bar': 'Some very exciting float'}
magic.foo = 2
magic.bar = 3.1416

内容的提问来源于stack exchange,提问作者P. B.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 14:39:00