【发布时间】:2021-11-28 05:35:39
【问题描述】:
在寻找初始化槽的便捷方法时,我产生了愚蠢?的想法错误地?使用__slots__字典,如下所示。
注意:在 SO 上有一个相关的 question,我之前将我的想法发布为answer,但我认为从中创建一个新问题可能更有用,因为我真的很想得到更多反馈。
因此,对于以下“技巧”的任何注释/建议/问题,我将不胜感激:
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
这样做可以/安全吗? 有没有什么缺点或可能的问题等?
编辑:
在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
【问题讨论】:
-
我喜欢这个! (尽管我敢打赌它会对类型检查器造成严重破坏——但是,嘿,你不能拥有一切!)
标签: python python-3.x slots