2017-06-11 48 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