2016-10-13 13 views
1

를 장식 피클 수 없습니다 내가 가지고있는 클래스를 장식하는 다음 코드 :파이썬 - 딜 : 클래스

import dill 
from collections import namedtuple 
from multiprocessing import Process 

def proxified(to_be_proxied): 
    b = namedtuple('d', []) 

    class Proxy(to_be_proxied, b): 
     pass 

    Proxy.__name__ = to_be_proxied.__name__ 
    return Proxy 


@proxified 
class MyClass: 
    def f(self): 
     print('hello!') 


pickled_cls = dill.dumps(MyClass) 


def new_process(clazz): 
    dill.loads(clazz)().f() 


p = Process(target=new_process, args=(pickled_cls,)) 
p.start() 
p.join() 

나는 다음과 같은 오류가 무엇입니까 장식 클래스 피클하려합니다 :

Traceback (most recent call last): 
    File "/usr/lib/python3.5/pickle.py", line 907, in save_global 
    obj2, parent = _getattribute(module, name) 
    File "/usr/lib/python3.5/pickle.py", line 265, in _getattribute 
    .format(name, obj)) 
AttributeError: Can't get local attribute 'proxified.<locals>.Proxy' on <function proxified at 0x7fbf7de4b8c8> 

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
    File "/home/carbolymer/example.py", line 108, in <module> 
    pickled_cls = dill.dumps(MyClass) 
    File "/usr/lib/python3.5/site-packages/dill/dill.py", line 243, in dumps 
    dump(obj, file, protocol, byref, fmode, recurse)#, strictio) 
    File "/usr/lib/python3.5/site-packages/dill/dill.py", line 236, in dump 
    pik.dump(obj) 
    File "/usr/lib/python3.5/pickle.py", line 408, in dump 
    self.save(obj) 
    File "/usr/lib/python3.5/pickle.py", line 475, in save 
    f(self, obj) # Call unbound method with explicit self 
    File "/usr/lib/python3.5/site-packages/dill/dill.py", line 1189, in save_type 
    StockPickler.save_global(pickler, obj) 
    File "/usr/lib/python3.5/pickle.py", line 911, in save_global 
    (obj, module_name, name)) 
_pickle.PicklingError: Can't pickle <class '__main__.proxified.<locals>.Proxy'>: it's not found as __main__.proxified.<locals>.Proxy 

딜을 사용하여 데코 레이팅 된 클래스를 피클 링하려면 어떻게해야합니까? 이 클래스를 인수로 별도의 프로세스로 전달하는 패스가 필요합니다. 아마도 더 간단한 방법일까요?

+1

당신이 예에서 일어나는 많은 일들이 있고, 그들 중 많은 직렬화 어려운을 피할 수 functools.wraps를 사용하여 클래스를 재 작성. 먼저,'multiprocessing' 대신에'multiprocess'를 사용할 것을 제안합니다. 그래서'pickle'와는 달리'dill'을 사용합니다. 둘째, 가능하면'namedtuple'을 피하십시오. 일련 번호를 지정하지만 특정 경우에만 작동합니다. 셋째, 가능한 경우 클래스 장식자를 피하십시오. 나는 '딜 (dill)'이 그들과 얼마나 잘 작동 하는지를 기억하지 못한다. 나는 가난하다고 생각한다. 마지막으로'dill.settings'을 시도해 볼 수 있습니다. 우선,'multiprocess'를 사용하고'namedtuple'을 사용하지 마십시오. –

답변

1

Gaël Varoquaux can be found here에서 제공하는 "왜 장식 기능을 산란하는 것은 고통 스럽습니까?"에 대한 좋은 설명입니다.

는 기본적으로 이러한 문제 :