2010-10-01 44 views
0

我想在multiprocessing.Queue上放一個scapy.layers.dhcp.BOOTP的實例。每次我打電話put()以下異常occures:不能把對象放在隊列上

Traceback (most recent call last): 
    File "/usr/lib/python2.6/multiprocessing/queues.py", line 242, in _feed 
    send(obj) 
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed 

原因試圖醃製直接使用pickle.dumps()也失敗的實例。但爲什麼這個班不適合挑選?

對於那些沒有誰Scapy的安裝:

class BOOTP(Packet): 
    name = "BOOTP" 
    fields_desc = [ ByteEnumField("op",1, {1:"BOOTREQUEST", 2:"BOOTREPLY"}), 
        ByteField("htype",1), 
        ByteField("hlen",6), 
        ByteField("hops",0), 
        IntField("xid",0), 
        ShortField("secs",0), 
        FlagsField("flags", 0, 16, "???????????????B"), 
        IPField("ciaddr","0.0.0.0"), 
        IPField("yiaddr","0.0.0.0"), 
        IPField("siaddr","0.0.0.0"), 
        IPField("giaddr","0.0.0.0"), 
        Field("chaddr","", "16s"), 
        Field("sname","","64s"), 
        Field("file","","128s"), 
        StrField("options","") ] 
    def guess_payload_class(self, payload): 
     if self.options[:len(dhcpmagic)] == dhcpmagic: 
      return DHCP 
     else: 
      return Packet.guess_payload_class(self, payload) 
    def extract_padding(self,s): 
     if self.options[:len(dhcpmagic)] == dhcpmagic: 
      # set BOOTP options to DHCP magic cookie and make rest a payload of DHCP options 
      payload = self.options[len(dhcpmagic):] 
      self.options = self.options[:len(dhcpmagic)] 
      return payload, None 
     else: 
      return "", None 
    def hashret(self): 
     return struct.pack("L", self.xid) 
    def answers(self, other): 
     if not isinstance(other, BOOTP): 
      return 0 
     return self.xid == other.xid 

是否有任何其他方式「運輸」這種情況下另一個子?

回答

1

嗯,問題是,你不能pickle功能類型。這就是你在做type(some_user_function)時得到的結果。看到這個:

>>> import types 
>>> pickle.dumps(types.FunctionType) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'picke' is not defined 
>>> pickle.dumps(types.FunctionType) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "C:\Python26\lib\pickle.py", line 1366, in dumps 
    Pickler(file, protocol).dump(obj) 
    File "C:\Python26\lib\pickle.py", line 224, in dump 
    self.save(obj) 
    File "C:\Python26\lib\pickle.py", line 286, in save 
    f(self, obj) # Call unbound method with explicit self 
    File "C:\Python26\lib\pickle.py", line 748, in save_global 
    (obj, module, name)) 
pickle.PicklingError: Can't pickle <type 'function'>: it's not found as __built 
n__.function 

所以這樣的函數類型存儲在你試圖發送的對象的某個地方。它不在你粘貼的代碼中,所以我想它在超類上。

也許你可以簡單地發送創建實例scapy.layers.dhcp.BOOTP所需的所有參數,而不是實例來避免該問題?

+0

我複製了所有相關的屬性到一個新的,自己創建的對象,因爲我沒有找到另一種解決方案。 – 2010-10-05 21:52:53

0

,可以幫助診斷這類問題的另一件事是使用鹹菜模塊代替cPickle的(必須得到由queues.py隱含使用)

我也有類似的情況,得到一個完全無益消息,

Can't pickle <type 'function'>: attribute lookup __builtin__.function failed 

我徘徊到調試器,找到的對象被酸洗,並試圖將其傳遞給

pickle.dump(myobj,open('outfile','w'),-1) 

和得到了更多幫助:

PicklingError: Can't pickle <function findAllRefs at 0x105809f50>: 
    it's not found as buildsys.repoclient.findAllRefs 

哪一個更直接地指向有問題的代碼。

0

我用的解決方案是str中的數據包,然後把它放在隊列...