나는 이것이 의 매우 좋은이라는 것을 알고 있지만 분명히 코드를 재 구조화하는 명백하고 확실한 답변 이외에이 질문에 대한 만족스러운 해결책을 결코 본 적이 없습니다.
불행히도, 그런 일을하는 것이 항상 실용적인 것은 아니며, 최후의 수단으로 은입니다. 다른 클래스 내에 정의 된 클래스의 인스턴스를 피클링하는 것이 가능합니다.
당신은 따라서
A callable object that will be called to create the initial version of the object. The next element of the tuple will provide arguments for this callable.
를 반환 할 수 __reduce__
function 상태의 파이썬 문서는 당신이 필요로하는 모든 해당 클래스의 인스턴스를 반환 할 수있는 개체입니다. 이 클래스 합니다 (__main__
수준에 살아야한다, 따라서) 그 자체가 picklable 수해야하며, 것처럼 간단 할 수있다 : 모든 것은 따라서 남아
class _NestedClassGetter(object):
"""
When called with the containing class as the first argument,
and the name of the nested class as the second argument,
returns an instance of the nested class.
"""
def __call__(self, containing_class, class_name):
nested_class = getattr(containing_class, class_name)
# return an instance of a nested_class. Some more intelligence could be
# applied for class construction if necessary.
return nested_class()
,에 __reduce__
방법에 적절한 인수를 반환하는 것입니다 FloatType :
class WidgetType(object):
class FloatType(object):
def __reduce__(self):
# return a class which can return this class when called with the
# appropriate tuple of arguments
return (_NestedClassGetter(), (WidgetType, self.__class__.__name__,))
결과는 중첩되지만 인스턴스 절인 할 수있는 클래스입니다 (추가 작업이 __state__
정보를로드/덤프 필요하지만 이것이 __reduce__
문서에 따라 비교적 간단합니다).
심하게 중첩 된 클래스의 경우이 동일한 기법 (약간의 코드 수정)을 적용 할 수 있습니다. 이에
import pickle
class ParentClass(object):
class NestedClass(object):
def __init__(self, var1):
self.var1 = var1
def __reduce__(self):
state = self.__dict__.copy()
return (_NestedClassGetter(),
(ParentClass, self.__class__.__name__,),
state,
)
class _NestedClassGetter(object):
"""
When called with the containing class as the first argument,
and the name of the nested class as the second argument,
returns an instance of the nested class.
"""
def __call__(self, containing_class, class_name):
nested_class = getattr(containing_class, class_name)
# make an instance of a simple object (this one will do), for which we can change the
# __class__ later on.
nested_instance = _NestedClassGetter()
# set the class of the instance, the __init__ will never be called on the class
# but the original state will be set later on by pickle.
nested_instance.__class__ = nested_class
return nested_instance
if __name__ == '__main__':
orig = ParentClass.NestedClass(var1=['hello', 'world'])
pickle.dump(orig, open('simple.pickle', 'w'))
pickled = pickle.load(open('simple.pickle', 'r'))
print type(pickled)
print pickled.var1
내 최종 문서는 다른 답변이 말한 것을 기억하는 것입니다 :
A가 완전히 예를 들어 일이 dill
대신 pickle
를 사용하는 경우
If you are in a position to do so, consider re-factoring your code to avoid the nested classes in the first place.
도니는 다르게, 사용자 이름이 우연의 일치인가? : p –
파이썬 피클 문서를 참고하십시오 : http://docs.python.org/library/pickle.html#the-pickle-protocol – joeforker
파이썬 3.4 이상에서,'inst = ObjectToPickle(); pickle.dumps (inst, 4)'는 잘 동작합니다. – Eponymous