2010-08-13 54 views
15

我想創建一個namedtuple,它代表一個短的位域中的各個標誌。我試圖對它進行子類化,以便在創建元組之前解壓位域。但是,我現在的嘗試是不工作:通過子類修改namedtuple的構造函數參數?

class Status(collections.namedtuple("Status", "started checking start_after_check checked error paused queued loaded")): 
    __slots__ =() 

    def __new__(cls, status): 
     super(cls).__new__(cls, status & 1, status & 2, status & 4, status & 8, status & 16, status & 32, status & 64, status & 128) 

現在,我與super()的經驗是有限的,我與__new__體驗幾乎是不存在的,所以我不知道如何做的是什麼(以我)神祕錯誤TypeError: super.__new__(Status): Status is not a subtype of super。谷歌搜索和挖掘文檔沒有產生任何啓發。

幫助?

回答

16

你幾乎擁有了:-)只是有兩個小的修正:

  1. 方法需要聲明
  2. super調用應該有兩個參數,cls狀態

生成的代碼如下所示:

import collections 

class Status(collections.namedtuple("Status", "started checking start_after_check checked error paused queued loaded")): 
    __slots__ =() 

    def __new__(cls, status): 
     return super(cls, Status).__new__(cls, status & 1, status & 2, status & 4, status & 8, status & 16, status & 32, status & 64, status & 128) 

它運行乾淨,就像你曾預計:

>>> print Status(47) 
Status(started=1, checking=2, start_after_check=4, checked=8, error=0, paused=32, queued=0, loaded=0) 
+4

應該是'超級(狀態,CLS)'! – knite 2014-10-03 22:21:53

10

我會避免super除非你明確地迎合多重繼承(希望不是這裏的情況;-)。只是這樣做...:

def __new__(cls, status): 
    return cls.__bases__[0].__new__(cls, 
            status & 1, status & 2, status & 4, 
            status & 8, status & 16, status & 32, 
            status & 64, status & 128) 
+0

工作就像一個魅力。謝謝! – 2010-08-13 14:16:46

+0

@Ben,不客氣! – 2010-08-13 15:49:32

+4

你也可以通過使用這個來減少代碼重複:'返回cls .__ bases __ [0] .__新__(cls,*(狀態&(1 << x)爲範圍內的x(0,8)))' – thejoshwolfe 2011-07-31 02:08:40