[PYTHON] namedtuple 인스턴스를 올바르게 피클 링하는 법
PYTHONnamedtuple 인스턴스를 올바르게 피클 링하는 법
나는 피클을 사용하는 법을 배우고있다. namedtuple 객체를 생성하고 목록에 추가 한 다음 해당 목록을 피클 링하려고했습니다. 그러나 다음과 같은 오류가 발생합니다.
pickle.PicklingError: Can't pickle <class '__main__.P'>: it's not found as __main__.P
함수 안에 배치하지 않고 코드를 실행하면 완벽하게 작동한다는 것을 알게되었습니다. 함수 내에서 래핑 될 때 객체를 피클하는 데 필요한 추가 단계가 있습니까?
여기 내 코드가 있습니다 :
from collections import namedtuple
import pickle
def pickle_test():
P = namedtuple("P", "one two three four")
my_list = []
abe = P("abraham", "lincoln", "vampire", "hunter")
my_list.append(abe)
f = open('abe.pickle', 'w')
pickle.dump(abe, f)
f.close()
pickle_test()
해결법
-
==============================
1.함수 밖에서 명명 된 튜플을 만듭니다.
함수 밖에서 명명 된 튜플을 만듭니다.
from collections import namedtuple import pickle P = namedtuple("P", "one two three four") def pickle_test(): my_list = [] abe = P("abraham", "lincoln", "vampire", "hunter") my_list.append(abe) f = open('abe.pickle', 'w') pickle.dump(abe, f) f.close() pickle_test()
이제 피클은 그것을 찾을 수 있습니다. 지금은 글로벌 모듈입니다. unpickling 할 때 모든 pickle 모듈은 __main __.P를 다시 찾습니다. 귀하의 버전에서, P는 로컬이며, pickle_test () 함수에 대한 것이고, 그것은 내성적이거나 수입 가능하지 않습니다.
namedtuple ()은 클래스 팩토리임을 기억해야합니다. 당신은 그것에게 매개 변수를주고 여러분이 인스턴스를 만들 수있는 클래스 객체를 리턴합니다. pickle은 인스턴스에 포함 된 데이터와 원래의 클래스에 대한 문자열 참조 만 저장하여 인스턴스를 다시 재구성합니다.
-
==============================
2.주된 대답에 대한 의견으로 내 질문을 추가 한 후에 동적으로 생성 된 명명 된 튜플 피클 가능 문제를 해결하는 방법을 발견했습니다. 이것은 (DB 쿼리 후) 런타임 동안 필드를 발견하고 있기 때문에 필자의 경우에 필요합니다.
주된 대답에 대한 의견으로 내 질문을 추가 한 후에 동적으로 생성 된 명명 된 튜플 피클 가능 문제를 해결하는 방법을 발견했습니다. 이것은 (DB 쿼리 후) 런타임 동안 필드를 발견하고 있기 때문에 필자의 경우에 필요합니다.
내가하는 일은 namedtuple을 효과적으로 __main__ 모듈로 옮겨서 원숭이 패치를하는 것뿐입니다.
def _CreateNamedOnMain(*args): import __main__ namedtupleClass = collections.namedtuple(*args) setattr(__main__, namedtupleClass.__name__, namedtupleClass) namedtupleClass.__module__ = "__main__" return namedtupleClass
주의하지 않으면 명명 된 튜플 이름 (args에 의해 제공됨)이 __main__의 다른 멤버를 덮어 쓸 수 있음을 명심하십시오.
-
==============================
3.또는 cloudpickle 또는 dill을 사용하여 직렬화 할 수 있습니다.
또는 cloudpickle 또는 dill을 사용하여 직렬화 할 수 있습니다.
from collections import namedtuple import cloudpickle import dill def dill_test(dynamic_names): P = namedtuple('P', dynamic_names) my_list = [] abe = P("abraham", "lincoln", "vampire", "hunter") my_list.append(abe) with open('deleteme.cloudpickle', 'wb') as f: cloudpickle.dump(abe, f) with open('deleteme.dill', 'wb') as f: dill.dump(abe, f) dill_test("one two three four")
-
==============================
4.다른 스레드에서이 대답을 발견했습니다. 이것은 명명 된 튜플의 명명에 관한 것입니다. 이것은 나를 위해 일했다 :
다른 스레드에서이 대답을 발견했습니다. 이것은 명명 된 튜플의 명명에 관한 것입니다. 이것은 나를 위해 일했다 :
group_t = namedtuple('group_t', 'field1, field2') # this will work mismatched_group_t = namedtuple('group_t', 'field1, field2') # this will throw the error
-
==============================
5.여기서 문제는 자식 프로세스가 객체 클래스를 가져올 수 없다는 것입니다.이 경우 P 클래스입니다. 다중 모델 프로젝트의 경우 클래스 P는 자식 프로세스가 사용되는 곳이면 어디서나 가져올 수 있어야합니다.
여기서 문제는 자식 프로세스가 객체 클래스를 가져올 수 없다는 것입니다.이 경우 P 클래스입니다. 다중 모델 프로젝트의 경우 클래스 P는 자식 프로세스가 사용되는 곳이면 어디서나 가져올 수 있어야합니다.
빠른 해결 방법은 globals ()에 영향을줌으로써 importable하게하는 것입니다.
globals()["P"] = P
from https://stackoverflow.com/questions/16377215/how-to-pickle-a-namedtuple-instance-correctly by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] virtualenv에 PyGtk 설치하기 (0) | 2018.11.11 |
---|---|
[PYTHON] 튜플을 사용할 때 ChoiceField에 빈 레이블이 표시되지 않습니다. (0) | 2018.11.11 |
[PYTHON] datetime 객체가 pytz로 지역화되었는지 확인하는 방법은 무엇입니까? (0) | 2018.11.11 |
[PYTHON] Python MySql Insert가 작동하지 않습니다. (0) | 2018.11.11 |
[PYTHON] Flask 앱의 공통 폴더 / 파일 구조 (0) | 2018.11.11 |