2013-01-24 3 views
1

다음 코드를 올바르게 실행 :인스턴스가 피클 링 될 Python 클래스를 꾸밀 수 있습니까?

import pickle 

class MyClass(): 
    def __init__(self, arg): 
     self.arg = arg 

a = MyClass('my arg') 
with open('/home/mahikeulbody/mypickle', 'wb') as file: 
    pickle.dump(a, file) 

하지만 멀티 톤 클래스 얻을 수있는 장식 추가 :

import pickle 

def multiton(cls): 
    instances = {} 
    def getinstance(arg): 
     if arg not in instances: 
      instances[arg] = cls(arg) 
     return instances[arg] 
    return getinstance 

@multiton 
class MyClass(): 
    def __init__(self, arg): 
     self.arg = arg 

a = MyClass('my arg') 
with open('/home/michel/mypickle', 'wb') as file: 
    pickle.dump(a, file) 

다음과 같은 오류 발생 :

pickle.dump(a, file) 
_pickle.PicklingError: Can't pickle <class '__main__.MyClass'>: it's not the same object as __main__.MyClass 

잘못 무엇입니까?

+1

어,이 데코레이터에는 그 이상의 문제가 있습니다. 그것은 단지 클래스가 아니며 공장 기능이되었습니다. 예를 들어, 수표를 입력하거나 하위 클래스로 분류 할 수 없습니다. – delnan

답변

2

Pickle은 클래스를 직접로드 할 수 있어야합니다. 데코레이터 을 공장 기능으로 바꿔서 피클이 클래스 자체를 가져올 수 없습니다.

(하지만 여전히 가져올 수 직접)는 '개인'클래스를 반환 별도의 공장 기능이 아닌 장식을 사용

class _MyClass(): 
    def __init__(self, arg): 
     self.arg = arg 

def MyClass(arg, instances={}): 
    if arg not in instances: 
     instances[arg] = _MyClass(arg) 
    return instances[arg] 
+0

당신의 대답의 부작용은 놀랍게도 인스턴스 변수가 다른 함수 호출간에 지속된다는 것을 발견했다는 것입니다. 이것은 약간 충격적입니다 ... – mahikeulbody

+0

@ user2008329 : [ "Least Astonishment"in Python : The Mutable Default Argument] (http://stackoverflow.com/q/1132941)를보십시오. 함수가 어떻게 작동하는지 알면 완벽하게 합리적입니다. :-) –

0

이를 위해, 나는 거의 아무것도를 직렬화 할 수 dill을 사용하십시오 파이썬.

>>> def multiton(cls): 
...  instances = {} 
...  def getinstance(arg): 
...   if arg not in instances: 
...    instances[arg] = cls(arg) 
...   return instances[arg] 
...  return getinstance 
... 
>>> @multiton 
... class MyClass(): 
...  def __init__(self, arg): 
...   self.arg = arg 
... 
>>> import dill 
>>>      
>>> a = MyClass('my arg') 
>>> b = dill.loads(dill.dumps(a)) 
>>> a 
<__main__.MyClass instance at 0x4d64558> 
>>> b 
<__main__.MyClass instance at 0x4d64800> 

딜은 또한 당신의 코드가 실패 할 경우 실패 할 당신의 산세 원인을 이해하고 돕는 some good tools 있습니다.

관련 문제