2017-05-24 18 views
2

私はJupyter 5でPython 3.6.1を使用しています。私の目標は、同じファイル上の同時追加をどのように管理するかをテストすることです。一貫性のないTypeError: '_io.TextIOWrapper'オブジェクトをシリアライズできません

これを達成するために、私は同じファイルに1行を追加する単純な関数を作成しました。私はmultiprocessing.PoolとPool.map()を使って並列に関数を実行します。

ここにJupyterノートのコードがあります。

セル1

from time import time 
from multiprocessing import Pool 
import portalocker 


def f(*args): 
    while time() < start + 1: 
     pass 
    with open('portalocker_test.txt', 'a') as f: 
     portalocker.lock(f, portalocker.LOCK_EX) 
     f.write(f'{time()}\n') 

セル2

start = time() 
with Pool(4) as p: 
    p.map(f, range(4)) 

セル3

with open('portalocker_test.txt', 'r') as f: 
    for line in f: 
     print(line, end='') 

私が期待した結果得れば、私はこのコードを実行する場合は、次のセルのうち

を3:

1495614277.189394 
1495614277.1893928 
1495614277.1893911 
1495614277.1894028 

しかし、私は(ノートブックを再起動せずに)再びセル2を実行する場合、私は得る:

--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-5-db9c07d32724> in <module>() 
     1 start = time() 
     2 with Pool(4) as p: 
----> 3  p.map(f, range(4)) 

/Users/xxx/Homebrew/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/pool.py in map(self, func, iterable, chunksize) 
    258   in a list that is returned. 
    259   ''' 
--> 260   return self._map_async(func, iterable, mapstar, chunksize).get() 
    261 
    262  def starmap(self, func, iterable, chunksize=None): 

/Users/xxx/Homebrew/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/pool.py in get(self, timeout) 
    606    return self._value 
    607   else: 
--> 608    raise self._value 
    609 
    610  def _set(self, i, obj): 

/Users/xxx/Homebrew/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/pool.py in _handle_tasks(taskqueue, put, outqueue, pool, cache) 
    383       break 
    384      try: 
--> 385       put(task) 
    386      except Exception as e: 
    387       job, ind = task[:2] 

/Users/xxx/Homebrew/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/connection.py in send(self, obj) 
    204   self._check_closed() 
    205   self._check_writable() 
--> 206   self._send_bytes(_ForkingPickler.dumps(obj)) 
    207 
    208  def recv_bytes(self, maxlength=None): 

/Users/xxx/Homebrew/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/reduction.py in dumps(cls, obj, protocol) 
    49  def dumps(cls, obj, protocol=None): 
    50   buf = io.BytesIO() 
---> 51   cls(buf, protocol).dump(obj) 
    52   return buf.getbuffer() 
    53 

TypeError: cannot serialize '_io.TextIOWrapper' object 

私はセル2を実行する前に、ファイルを読み込む場合、私は決して場合は、同じエラーが、上げますセル2を実行する前にファイルを開いて、すべてうまくいく。前にファイルを開くと、そのエラーが発生します。 これは私にかなり矛盾しています。何が起こっている?どのようにそれを解決するには?

また、ポータルロックを使用してもしなくても、この動作は変更されないため、問題はポーカーロックではありません。私は単純なpythonでそれをチェックしていないが、私は本当にJupyterでそれを実行することに興味があります。

+0

あなたのファイルオブジェクトと関数が同じ名前 'F'を持っている理由は? –

答えて

2

問題は、あなたの場合には、異なるオブジェクトに同じ名前を避けるべきであるということですfからfunctionに関数名を変更

  • を助けるべきでは(またはfは異なる別の名前)

    セル1

    from time import time 
    from multiprocessing import Pool 
    import portalocker 
    
    
    def function(*args): 
        while time() < start + 1: 
         pass 
        with open('portalocker_test.txt', 'a') as f: 
         portalocker.lock(f, portalocker.LOCK_EX) 
         f.write(f'{time()}\n') 
    

    セル2

    start = time() 
    with Pool(4) as p: 
        p.map(function, range(4)) 
    

又は

  • filefからopenを用いて得られた名前を変更するファイルオブジェクト(またはfとは異なる別の名前):

    セル1

    from time import time 
    from multiprocessing import Pool 
    import portalocker 
    
    
    def f(*args): 
        while time() < start + 1: 
         pass 
        with open('portalocker_test.txt', 'a') as file: 
         portalocker.lock(file, portalocker.LOCK_EX) 
         file.write(f'{time()}\n') 
    

    セル3

    with open('portalocker_test.txt', 'r') as file: 
        for line in file: 
         print(line, end='') 
    

または両方

+0

ありがとう!私はそれについて考えなかった。 –

+0

@alec_djinn:あなたは歓迎です –

関連する問題