2016-09-28 7 views
2

私はネットワークソケットを介して相互に通信するサーバーとクライアントプログラムを持っています。ネットワークソケット経由で送信するPythonのscandir.DirEntryをシリアル化する方法は?

私がしたいのは、scandir.scandir()から得られたディレクトリエントリ(scandir.DirEntry)をソケット経由で送信することです。どのように

File "untitled.py", line 5, in <module> 
    data = pickle.dumps(item) 
File "C:\Python27\Lib\pickle.py", line 1374, in dumps 
    Pickler(file, protocol).dump(obj) 
File "C:\Python27\Lib\pickle.py", line 224, in dump 
    self.save(obj) 
File "C:\Python27\Lib\pickle.py", line 306, in save 
    rv = reduce(self.proto) 
File "C:\Python27\Lib\copy_reg.py", line 70, in _reduce_ex 
    raise TypeError, "can't pickle %s objects" % base.__name__ 

TypeError: can't pickle DirEntry objects 

import scandir, pickle 

s = scandir.scandir("D:\\PYTHON") 
entry = s.next() 
data = pickle.dumps(entry) 

しかし、私は次のエラー・スタックを取得しています:今、私はpicklecPickleモジュールを使用していて、次の(のみ抜粋)が出ているために

このエラーを取り除くことはできますか?

私はmarshallまたはJSONを使用して聞いたことがあります。 更新JSONは、オブジェクト内のすべてのデータをダンプしていません。

オブジェクトをソケット経由で送信する方法はまったく異なりますか?

ご協力いただきありがとうございます。

+0

class PseudoDirEntry: def __init__(self, name, path, is_dir, stat): self.name = name self.path = path self._is_dir = is_dir self._stat = stat def is_dir(self): return self._is_dir def stat(self): return self._stat 

そして:

組み合わせ、それは次のようになりますか? –

+0

@SimonBlack:まさに、私はアクセス可能なデータだけを送ることによって部分的にそれを見つけました。しかし、 'is_dir()'のような、クラスのメソッドの動作をエミュレートする方法はありますか?この 'is_dir()'メソッドの実際のデータはどこにありますか? –

答えて

0

まあ私自身はこのscandir.DirEntryような非標準クラスのインスタンスのために、最善の方法は、標準オブジェクトdictlist(のようなの(おそらくネストされた)の組み合わせにクラスのメンバデータを変換にあることを考え出しました等。)。

例えば、scandir.DirEntryの特定の場合、次のようにすることができます。私の目的のために、私はデータのみを必要とするが

import scandir, pickle 

s = scandir.scandir("D:\\PYTHON") 
entry = s.next() 

# first convert the stat object to st_ 
st = entry.stat() 
st_ = {'st_mode':st.st_mode, 'st_size':st.st_size,\ 
    'st_atime':st.st_atime, 'st_mtime':st.st_mtime,\ 
    'st_ctime':st.st_ctime} 

# now convert the entry object to entry_ 
entry_ = {'name':entry.name, 'is_dir':entry.is_dir(), \ 
'path':entry.path, 'stat':st_} 

# one may need some other class member data also as necessary 

# now pickle the converted entry_ 
data = pickle.dumps(entry_) 

、もう一方の端でunpickle化した後、一つはscandir.DirEntryオブジェクトのエントリ」をunpickle化するにunpickle entry_を再構築する必要があるかもしれません。 しかし、私はまだクラスインスタンスを再構築する方法と、is_dir()stat()のようなメソッドの振る舞いのためのデータを設定する方法を見つけ出していません。

1

はい、os.DirEntryオブジェクトは短命であり、実際には保持されず、シリアル化されていません。それらのデータをシリアル化する必要がある場合は、必要な属性のdictバージョンをシリアル化(pickle)します。

os.DirEntryインスタンスのように歩き回って突き抜けるオブジェクトに逆シリアル化するには、必要なものを模倣するPseudoDirEntryクラスを作成します。

既にstatオブジェクトを直接シリアル化することができます。これにより、フィールドを選択する手間が省けます。あなたがオブジェクト内の関連データをソケットを介してオブジェクトを送信しないようにするのはなぜ

>>> import os, pickle 
>>> entry = list(os.scandir())[0] 
>>> pickled = pickle.dumps({'name': entry.name, 'path': entry.path, 'is_dir': entry.is_dir(), 'stat': entry.stat()}) 
>>> loaded = pickle.loads(pickled) 
>>> pseudo = PseudoDirEntry(loaded['name'], loaded['path'], loaded['is_dir'], loaded['stat']) 
>>> pseudo.name 
'.DS_Store' 
>>> pseudo.is_dir() 
False 
>>> pseudo.stat() 
os.stat_result(st_mode=33188, st_ino=8370294, st_dev=16777220, st_nlink=1, st_uid=502, st_gid=20, st_size=8196, st_atime=1478356967, st_mtime=1477601172, st_ctime=1477601172) 
関連する問題