2016-09-28 3 views
2

네트워크 소켓을 통해 서로 통신하는 서버 및 클라이언트 프로그램이 있습니다.네트워크 소켓을 통해 전송하기 위해 파이썬에서 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

왜 당신이 소켓을 통해 객체를 전송 하시겠습니까 아니라 관련 데이터를 객체 내에서? –

+0

@SimonBlack : 정확히, 나는 접근 가능한 데이터 만 보내어 부분적으로 알아 냈습니다. 그러나'is_dir()'과 같은 클래스의 메소드의 동작을 에뮬레이션하는 방법은 무엇입니까? 이'is_dir()'메소드의 실제 데이터는 어디에 있습니까? –

답변

0

잘 나는 나 자신이 scandir.DirEntry 같은 비표준 클래스의 인스턴스를, 가장 좋은 방법은 같은 표준 객체 (list, dict의 (아마도 중첩 된) 조합에 클래스 멤버 데이터를 변환 에 있음을 알아 낸 기타.).

예를 들어, 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_) 

, 다른 쪽 끝에서 unpickling 후, 하나는 scandir.DirEntry 목적 '항목을'unpickled하는 unpickled entry_를 재구성 해야 할 수도 있습니다. 그러나 클래스 인스턴스를 재구성하고 메서드 동작에 대한 데이터를 설정하는 방법을 아직 알지 못했습니다.is_dir(), stat() 등이 있습니다.

1

예, os.DirEntry 개체는 수명이 짧거나, 실제로 주변에 보관되거나 직렬화되지 않습니다. 직렬화 할 데이터가 필요하다면 자신이 원하는대로 속성의 dict 버전을 serialize (pickle)하십시오.

os.DirEntry 인스턴스처럼 걸어 다니면서 돌팔이로 묶는 객체로 역 직렬화하려면 필요한 것을 모방 한 PseudoDirEntry 클래스를 만듭니다.

이미 통계 개체를 직접 직렬화 할 수 있으므로 필드를 선택하지 않아도됩니다.

결합, 그것은 다음과 같이 보일 것이다 : 다음

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 

과 :

>>> 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) 
관련 문제