2014-07-09 2 views
4

멀티 큐의 사용과 충돌 multiprocessing.Queue을 사용하십시오. multiprocessing.Queue 이후팩토리 메소드 패턴은 I 제품 클래스의 기본 클래스 변수화하는 팩토리 메소드 패턴을 구현 한

이 (Pickle documentation의 설명 참조) 개체를 저장 Pickle를 사용하고, Wrapper는 최상위 수준에 정의되어 있지, 나는 다음과 같은 오류 얻을 :

PicklingError: Can't pickle <class 'Wrapper'>: attribute lookup Wrapper failed 

을 나는이 answer에서 해결 방법을 사용 다른 오류가 발생합니다.

AttributeError: ("type object 'ParentClass' has no attribute 'Wrapper'", <main._NestedClassGetter object at 0x8c7fe4c>, (<class 'ParentClass'>, 'Wrapper')) 

프로세스간에 이러한 종류의 개체를 공유하는 솔루션이 있습니까?

+1

'Wrapper'는'factory' 함수 안에 중첩 된'ParentClass' 안에 중첩되어 있지 않기 때문에이 문제를 해결할 수 없습니다. – dano

+0

+1 당신 말이 맞아요! – synack

답변

1

Pickle documentation에 따르면, 질문에 링크 된 해결 방법을 수정할 수 있습니다 :

class _NestedClassGetter(object): 
    """ 
    From: http://stackoverflow.com/a/11493777/741316 
    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, factory_method, base): 
     nested_class = factory_method(base) 

     # 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 

__reduce__ 방법 :

def __reduce__(self): 
     state = self.__dict__.copy() 
     return (_NestedClassGetter(), 
       (factory, ParentClass), state,) 

덕분에 자신의 의견에 대한 @dano합니다.

1

가장 좋은 해결책은 코드를 동적으로 선언 된 클래스가 아닌 구조로 재구성하는 것이지만 그렇지 않다고 가정하면 코드를 피할 수 있습니다.

그리고 당신의 Wrapper 클래스에이 방법 :

def wrapper_unpickler(factory, cls, reconstructor, *args): 
    return reconstructor(*((factory(cls),) + args)) 

는 기본적으로, 당신은 공장 funciton + 포장 클래스의 동적으로 생성 Wrapper 클래스를 교환하고 있습니다 :

def __reduce__(self): 
    r = super(Wrapper, self).__reduce__() 
    return (wrapper_unpickler, 
      ((factory, ParentClass, r[0]) + r[1][1:])) + r[2:] 

이 모듈에이 기능을 추가 피클 링 할 때, 그리고 unpickling 할 때 Wrapper 클래스를 다시 동적으로 생성하고 (랩핑 된 유형을 팩토리에 전달) Wrapper의 래핑 된 클래스를 스와핑합니다.

+0

하지만 내가 말했듯이 : 공장 목표 패턴을 사용하기 위해 내 목표는 동적으로 선언 된 클래스를 사용하는 것입니다. 이 패턴에 의해 제공된 동일한 기능을 갖기 위해 코드를 구조화하라는 제안은 어떤 방식으로 나타 납니까? – synack

+0

@ Kits89 그래서 내가 "그렇다고 생각하지 않는다"라고 말하면서, "그것이 불가능하다고 가정"을 의미합니다. 그 대답의 나머지 부분은 문제 해결을위한 실질적인 해결책을 제시합니다! –

+0

나는 동등한 패턴이 있는지 궁금해했다. 동적으로 생성 된 클래스를 사용하지 않을 것입니다. 예, 답장을 보내 주셔서 감사합니다. 제가 끝까지 생각해 낸 것과 거의 같습니다 (다른 답변 참조). 도와 줘서 고마워. – synack

관련 문제