首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python __slots__元类问题

Python __slots__元类问题
EN

Stack Overflow用户
提问于 2017-06-11 18:22:48
回答 1查看 396关注 0票数 0

我目前正在使用type()实现时隙元类

代码语言:javascript
复制
type(i, (), {'__slots__': tuple(data)

当然,理想情况下,我会保留插槽,因为我有一个usecase,它将受益于它们更小的内存占用和更快的访问速度。

当我这么做时:

代码语言:javascript
复制
dir(slotted_class)
>>>['__class__',
 '__delattr__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__slots__',
 '__str__',
 '__subclasshook__',
 'slotted_attribute1',
 'slotted_attribute2',
 'slotted_attribute3',
 'slotted_attribute4']

然而,当我跑步时:

代码语言:javascript
复制
slottedclass.slotted_attribute1

我得到以下错误:

代码语言:javascript
复制
    >>> AttributeError                            Traceback (most recent call last)
<ipython-input-58-88291109fa74> in <module>()
----> 1 slotted_class.slotted_attribute1

AttributeError: slotted_attribute1

编辑:关于更多的信息和更多的困惑:如果我直接实现一个不使用元类的等价物:

代码语言:javascript
复制
class slottedclass_non_meta(object):
__slots__ = ['slotted_attribute1', 'slotted_attribute2', 'slotted_attribute3', 'slotted_attribute4']

def __init__(self, slotted_attribute1, slotted_attribute2, slotted_attribute3, slotted_attribute4):
    self.slotted_attribute1, self.slotted_attribute2, self.slotted_attribute3, self.slotted_attribute4 = slotted_attribute1, slotted_attribute2, slotted_attribute3, slotted_attribute4

然后进行这个比较,dir(slottedclass) == dir(slottedclass_non_meta)

代码语言:javascript
复制
>>> True
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-06-12 10:52:50

这可能只是data变量上的一些错误。确保它是一个可迭代的字符串序列。

在我的交互环境中尝试这样做是完美的:

代码语言:javascript
复制
In [162]: m = type("m", (), {"__slots__": ("test1",)})

In [163]: m.test1
Out[163]: <member 'test1' of 'm' objects>

In [164]: n = m()

In [165]: n.test1 = 10

In [166]: n.test1
Out[166]: 10

其他考虑因素如下:

  • 您不需要说您正在“使用元类”(尽管从技术上讲是这样)--只需说您正在通过调用type动态创建类。在阅读问题标题时,大多数人会认为您正在尝试将type本身专门化,并将__slots__包含在其中。
  • 在您粘贴的示例代码中,您没有动态创建类的__init__方法:因此,您显然无法在创建类时传递名称参数,并使它们在实例上自动设置,就像您在显式类上所做的那样。

如果第二个主题是您的问题,我不再继承object (隐含的,但他调用的是空的- () -第二个参数),而是使用一个通用的__init__方法创建一个基类,将这些kwargs设置为属性:

代码语言:javascript
复制
class Base:
   __slots__ = ()
   def __init__(self, **kwargs):
       for key, value in kwargs.items():
           setattr(self, key, value)

slotted_class  = type("slotted_class", (Base,), {"__slots__": ...})
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44487217

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档