Python 使用 __slots__ 字典进行初始化是否有效?

2024-03-12

在寻找一种方便的方法来初始化插槽时,我有stupid?的想法wrongly? using __slots__字典如下图所示。

注:有一个相关的question https://stackoverflow.com/questions/41893267/how-to-use-slots-with-initialization-of-attributes/69491913在我之前发布过我的想法的地方answer https://stackoverflow.com/a/69491913/13613140,但我认为从中创建一个新问题可能更有用,因为我真的很想获得更多反馈。

所以我很感激以下“技巧”的任何注释/建议/问题:

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

这样做可以/安全吗? 有什么缺点或者可能出现的问题等吗?

Edit:

After 亚历克斯·韦古德 https://stackoverflow.com/users/13990016/alex-waygood提到了 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

据我所知know,定义能力的预期用途__slots__ as a dict用于文档目的。

(我不知道在哪里(如果有的话)记录了这一点,也不知道它何时被添加到 Python 中。我确实知道这种行为在 Python 3.8、3.9、3.10 以及截至 14/10 的 3.11 alpha 0 中是一致的/ 2021。我还没有在 Python

如果我有课Foo,像这样:

class Foo:
    """The Foo class is for doing Foo-y things (obviously)."""
    
    __slots__ = {
        'bar': 'Some information about the bar attribute',
        'baz': 'Some information about the baz attribute'
    }

然后打电话help(Foo)在交互式终端中会产生以下输出:

>>> help(Foo)
Help on class Foo in module __main__:

class Foo(builtins.object)
 |  The Foo class is for doing Foo-y things (obviously).
 |  
 |  Data descriptors defined here:
 |  
 |  bar
 |      Some information about the bar attribute
 |  
 |  baz
 |      Some information about the baz attribute

如果我打电话help()在你的Magic类,但是,我得到以下输出:

>>> help(Magic)
Help on class Magic in module __main__:

class Magic(Slotted)
 |  Magic(*args, **kwargs)
 |  
 |  Method resolution order:
 |      Magic
 |      Slotted
 |      builtins.object
 |  
 |  Data descriptors defined here:
 |  
 |  bar
 |  
 |  foo
 |  
 |  ----------------------------------------------------------------------
 |  Static methods inherited from Slotted:
 |  
 |  __new__(cls, *args, **kwargs)
 |      Create and return a new object.  See help(type) for accurate signature.

话虽如此——我认为没有任何地方可以表明你can't做你在问题中建议的事情。它似乎工作得很好,所以如果你不太关心你的类的文档,并且它使你的代码更加干燥,我说那就去做吧!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 使用 __slots__ 字典进行初始化是否有效? 的相关文章

随机推荐