2016-10-13 40 views
1

我有下面的代碼,其裝飾類:的Python - 蘿:不能泡菜裝飾

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

你有很多東西在這個例子中繼續,其中許多是難以進行序列化的類。首先,我建議使用'multiprocess',而不是'multiprocessing',讓您充分利用'dill'而不是'pickle'。其次,如果可以的話,避免使用'namedtuple'。他們將序列化,但只在某些情況下工作。第三,如果可以的話,避免使用類裝飾器。我不記得'蒔蘿'對他們有多麼好,我覺得不好。最後,你可以嘗試的東西像dill'如何處理'全局變化的不同'dill.settings'。首先,使用'multiprocess'並且不要使用'namedtuple'。 –

回答

1

的一個很好的解釋「爲什麼酸洗裝飾功能是痛苦的」,由蓋爾·Varoquaux can be found here提供。

基本上重寫使用functools.wraps能避免這些問題:)