2016-10-07 1 views
0

클래스 내에 namedtuple이 있습니다. 딜 (dill)을 사용하여 절편을 만들 때 최상위 모듈에서 namedtuple 객체를 찾을 수 없다는 고전적인 문제가 발생합니다.파이썬 딜 : Pickle namedtuple이 작동하지 않는 것 같습니다.

이것은 self.TM 및 기타에 대한 기본 할당이며, 로그를 구문 분석 할 때 namedtuple을 동적으로 할당합니다.

그러나 산세 :

if __name__ == "__main__": 

    filename = 'dbggen_rx_loc_2-llh_rtm_lla_out_20160929_130711_day2_4381_JN2_SN64_rtmproc_2M5M.txt' 
    N = NNRTMParse(filename) 
    N.parse() 
    N.get_rx_loc('oak484_bora-llh') 

    filehandler = open("NNRTMParse_JB2-SN052.obj","wb") 
    pickle.dump(N,filehandler) 
    filehandler.close() 






Traceback (most recent call last): 
    File "C:/NN_Hardware/spos_proc/NNRTMParse.py", line 937, in <module> 
    pickle.dump(N,filehandler) 
    File "C:\Python27\lib\site-packages\dill\dill.py", line 236, in dump 
    pik.dump(obj) 
    File "C:\Python27\lib\pickle.py", line 224, in dump 
    self.save(obj) 
    File "C:\Python27\lib\pickle.py", line 331, in save 
    self.save_reduce(obj=obj, *rv) 
    File "C:\Python27\lib\pickle.py", line 419, in save_reduce 
    save(state) 
    File "C:\Python27\lib\pickle.py", line 286, in save 
    f(self, obj) # Call unbound method with explicit self 
    File "C:\Python27\lib\site-packages\dill\dill.py", line 835, in save_module_dict 
    StockPickler.save_dict(pickler, obj) 
    File "C:\Python27\lib\pickle.py", line 649, in save_dict 
    self._batch_setitems(obj.iteritems()) 
    File "C:\Python27\lib\pickle.py", line 681, in _batch_setitems 
    save(v) 
    File "C:\Python27\lib\pickle.py", line 286, in save 
    f(self, obj) # Call unbound method with explicit self 
    File "C:\Python27\lib\site-packages\dill\dill.py", line 1189, in save_type 
    StockPickler.save_global(pickler, obj) 
    File "C:\Python27\lib\pickle.py", line 748, in save_global 
    (obj, module, name)) 
pickle.PicklingError: Can't pickle <class '__main__.TM'>: it's not found as __main__.TM 

나는 밖으로 어떤 방법이 있는지 모르겠습니다. 다른 방법은 피클 할 데이터 프레임을 니트로 픽업하기 위해 경로를 따라 라우팅해야합니다.

도움이 매우 감사합니다.

+0

안녕하세요, 저는 '딜 작성자'입니다. 나는이 문제가 https://github.com/uqfoundation/dill/issues/132에있는 것일 수도 있다고 생각한다. '딜 (dill)'과 함께 '명명 된 튜플 (namedtuple)'은 "나쁘게"라는 이름이 붙지 않는 한 꽤 잘게됩니다. 기본적으로 위의 문제와 같이 이름을 지정한 다음 포인터 참조를 사용하여 원하는대로 작업 할 수 있습니다. 열쇠는 '__name__'과 같은 0 번째 인수를가집니다. –

+0

@MikeMcKerns 답장을 보내 주셔서 감사합니다. 나는 잘 모르겠다. 나는 "나쁜"이름을 지었다. I는 시도 - namedtuple TM = ('TM'tmeas_fields) TM .__ name__ = "TM" 프린트 TM 출력 : <클래스 '__main __ TM.'>입니다. pickle.PicklingError : __main __. TM '>을 pickle 할 수 없습니다 : __main__.TM – rrkarts

답변

0

문제는 self.TMnamedtuple입니다. namedtuple을 클래스 속성으로 사용하지 않으면 클래스가 피클해야합니다.

# file: xxx.py 
from collections import namedtuple 

class NNRTMParse(object): 

    def __init__(self): 
    TM = namedtuple("TM", 'a') 
    CFH = namedtuple("CFH", 'b') 
    print CFH 

그것은 다음과 같이 작동합니다 :

>>> from xxx import * 
>>> a = NNRTMParse() 
<class 'xxx.CFH'> 
>>> import dill 
>>> dill.copy(a) 
<xxx.NNRTMParse object at 0x107da3350> 

그러나 바로이 속성으로 namedtuple를 사용하려고로, 당신이보고있는 오류와 함께 실패합니다.

__reduce__ 메서드 (https://docs.python.org/3/library/pickle.html#object.reduce)를 추가하여 pickle에 클래스 인스턴스의 상태를 직렬화하는 방법을 알려줄 것을 제안합니다.

+0

이 없으므로 _self.TM_이 없어도 이전에 언급 한 내용과 똑같은 방식으로 여기에서 제안한 바를 정확하게 시도했습니다. _namedtuple_을 속성으로 사용하십시오. 하지만 여전히 같은 오류가 발생합니다. 당신의 대체 제안에 _self.TM_을 사용하고 _reduce_()를 넣으면. 확실한지 잘 모르겠지만 여전히 smae 오류가 발생합니다. def __reduce __ (self) : return (self .__ class__, (self.TM, self.PM, self.SPOSX, self.CFH)) – rrkarts

+0

흠, 코드의 전체 축소 버전을 보는 것이 도움이 될 것입니다. - 오류가 발생하는 이유는 위의 버전이'self.TM'을 사용할 때까지 작동하기 때문입니다. –

관련 문제