2017-06-11 50 views
0

我目前正在实施开槽元类使用type()Python的__slots__元类问题

type(i,(), {'__slots__': tuple(data) 

我当然会非常有槽保持,因为我有一个会从他们的更小的内存占用和提高访问速度受益的用例。

当我这样做:但是当我运行

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'] 

slottedclass.slotted_attribute1 

我收到以下错误:

>>> AttributeError       Traceback (most recent call last) 
<ipython-input-58-88291109fa74> in <module>() 
----> 1 slotted_class.slotted_attribute1 

AttributeError: slotted_attribute1 

编辑:欲了解更多的信息,甚至更多的困惑: 如果我直接实施一个等价物而不使用元类:

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 

然后,让这个比较 目录(slottedclass)==目录(slottedclass_non_meta)

>>> True 
+0

什么是完整的错误?这看起来被截断了。 – Carcigenicate

+1

你的对象,而不是“slotted_class”做“slottedClass”大写C那么试试这个“slotted_class.slotted_attribute1” –

+0

我道歉,这仅仅是一个占位符,我写了这个问题本身。然而,错误真的很简单。我将增加整个回溯 – SerialDev

回答

1

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

我的互动环境尝试这种完美无缺:

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__方法FO您的动态创建的类:所以你obviusly将无法转嫁类创建名称参数,并使它们在例如自动设置,为你做你明确的阶级。

如果第二个话题是你的问题,我建议的,而不是object继承(暗示,但他空 - () - 第二个参数来调用),与通用__init__方法创建一个基类来设置kwargs的属性:

class Base: 
    __slots__ =() 
    def __init__(self, **kwargs): 
     for key, value in kwargs.items(): 
      setattr(self, key, value) 

slotted_class = type("slotted_class", (Base,), {"__slots__": ...}) 
+0

谢谢您花时间回答,这实际上是有帮助的 – SerialDev