[python] 개체 저장 및로드 및 피클 사용

pickle모듈을 사용하여 개체를 저장하고로드하려고 합니다.
먼저 객체를 선언합니다.

>>> class Fruits:pass
...
>>> banana = Fruits()

>>> banana.color = 'yellow'
>>> banana.value = 30

그 후 ‘Fruits.obj’라는 파일을 엽니 다 (이전에는 새 .txt 파일을 만들고 이름을 ‘Fruits.obj’로 변경했습니다).

>>> import pickle
>>> filehandler = open(b"Fruits.obj","wb")
>>> pickle.dump(banana,filehandler)

이 작업을 수행 한 후 세션을 닫고 새 세션을 시작하고 다음 세션을 넣습니다 (저장해야하는 개체에 액세스하려고 시도 함).

file = open("Fruits.obj",'r')
object_file = pickle.load(file)

하지만이 메시지가 있습니다.

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python31\lib\pickle.py", line 1365, in load
encoding=encoding, errors=errors).load()
ValueError: read() from the underlying stream did notreturn bytes

이 메시지를 이해하지 못하기 때문에 어떻게해야할지 모르겠습니다. 누구든지 내 개체 ‘바나나’를로드 할 수있는 방법을 알고 있습니까? 감사합니다!

편집하다 :
여러분 중 일부는 다음 같이 말했습니다.

>>> import pickle
>>> file = open("Fruits.obj",'rb')

문제는 없었지만 다음은 다음과 같습니다.

>>> object_file = pickle.load(file)

그리고 오류가 있습니다.

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python31\lib\pickle.py", line 1365, in load
encoding=encoding, errors=errors).load()
EOFError



답변

두 번째 문제는 다음과 같습니다.

 Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "C:\Python31\lib\pickle.py", line
 1365, in load encoding=encoding,
 errors=errors).load() EOFError

파일의 내용을 읽은 후에는 파일 포인터가 파일의 끝에있게되며 더 이상 읽을 데이터가 없습니다. 처음부터 다시 읽을 수 있도록 파일을 되 감아 야합니다.

file.seek(0)

하지만 일반적으로 원하는 것은 컨텍스트 관리자를 사용하여 파일을 열고 데이터를 읽는 것입니다. 이렇게하면 블록 실행이 완료된 후 파일이 자동으로 닫히므로 파일 작업을 의미있는 청크로 구성하는 데 도움이됩니다.

마지막으로, cPickle은 C에서 pickle 모듈의 더 빠른 구현입니다. 따라서 :

In [1]: import cPickle

In [2]: d = {"a": 1, "b": 2}

In [4]: with open(r"someobject.pickle", "wb") as output_file:
   ...:     cPickle.dump(d, output_file)
   ...:

# pickle_file will be closed at this point, preventing your from accessing it any further

In [5]: with open(r"someobject.pickle", "rb") as input_file:
   ...:     e = cPickle.load(input_file)
   ...:

In [7]: print e
------> print(e)
{'a': 1, 'b': 2}


답변

다음은 나를 위해 작동합니다.

class Fruits: pass

banana = Fruits()

banana.color = 'yellow'
banana.value = 30

import pickle

filehandler = open("Fruits.obj","wb")
pickle.dump(banana,filehandler)
filehandler.close()

file = open("Fruits.obj",'rb')
object_file = pickle.load(file)
file.close()

print(object_file.color, object_file.value, sep=', ')
# yellow, 30


답변

바이너리로 읽는 것을 잊고 있습니다.

쓰기 부분에는 다음이 있습니다.

open(b"Fruits.obj","wb") # Note the wb part (Write Binary)

읽기 부분에는 다음이 있습니다.

file = open("Fruits.obj",'r') # Note the r part, there should be a b too

따라서 다음으로 대체하십시오.

file = open("Fruits.obj",'rb')

그리고 그것은 작동합니다 🙂


두 번째 오류는 파일을 제대로 닫거나 동기화하지 않아서 발생할 가능성이 큽니다.

다음 코드를 작성해보십시오.

>>> import pickle
>>> filehandler = open(b"Fruits.obj","wb")
>>> pickle.dump(banana,filehandler)
>>> filehandler.close()

그리고 이것은 (변경되지 않음) 읽을 수 있습니다.

>>> import pickle
>>> file = open("Fruits.obj",'rb')
>>> object_file = pickle.load(file)

깔끔한 버전은 with문을 사용합니다 .

쓰기 :

>>> import pickle
>>> with open('Fruits.obj', 'wb') as fp:
>>>     pickle.dump(banana, fp)

읽기 :

>>> import pickle
>>> with open('Fruits.obj', 'rb') as fp:
>>>     banana = pickle.load(fp)


답변

이 경우 항상 바이너리 모드로 엽니 다.

file = open("Fruits.obj",'rb')


답변

바이너리 모드에서 파일을 열지 않았습니다.

open("Fruits.obj",'rb')

작동해야합니다.

두 번째 오류의 경우 파일이 비어있을 가능성이 높습니다. 이는 실수로 파일을 비우거나 잘못된 파일 이름 등을 사용했음을 의미합니다.

(이것은 당신이 정말로 세션을 닫았다 고 가정합니다. 그렇지 않다면 쓰기와 읽기 사이에 파일을 닫지 않았기 때문입니다).

귀하의 코드를 테스트했으며 작동합니다.


답변

세션 전반에 걸쳐 클래스 인스턴스를 저장하려는 것 같으며 사용하는 pickle것이 적절한 방법입니다. 그러나 klepto사전 인터페이스에 개체 저장을 추상화 하는 패키지가 있으므로 개체를 선택하여 파일에 저장하거나 (아래 그림 참조) 개체를 선택하여 데이터베이스에 저장하거나 pickle use json 또는 다른 많은 옵션을 사용하십시오. 좋은 점은 klepto공통 인터페이스로 추상화함으로써 쉽게 파일에 피클 링을 통해 저장하는 방법에 대한 낮은 수준의 세부 정보를 기억할 필요가 없다는 것입니다.

동적으로 추가 된 클래스 속성에 대해 작동하지만 pickle은 수행 할 수 없습니다.

dude@hilbert>$ python
Python 2.7.6 (default, Nov 12 2013, 13:26:39)
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from klepto.archives import file_archive
>>> db = file_archive('fruits.txt')
>>> class Fruits: pass
...
>>> banana = Fruits()
>>> banana.color = 'yellow'
>>> banana.value = 30
>>>
>>> db['banana'] = banana
>>> db.dump()
>>> 

그런 다음 다시 시작합니다 …

dude@hilbert>$ python
Python 2.7.6 (default, Nov 12 2013, 13:26:39)
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from klepto.archives import file_archive
>>> db = file_archive('fruits.txt')
>>> db.load()
>>>
>>> db['banana'].color
'yellow'
>>> 

Klepto python2 및 python3에서 작동합니다.

여기에서 코드 받기 :
https://github.com/uqfoundation


답변

anycache 를 사용 하여 작업을 수행 할 수 있습니다 . myfunc인스턴스를 생성 하는 함수가 있다고 가정합니다 .

from anycache import anycache

class Fruits:pass

@anycache(cachedir='/path/to/your/cache')
def myfunc()
    banana = Fruits()
    banana.color = 'yellow'
    banana.value = 30
return banana

Anycache myfunc는 처음에 호출 cachedir하고 고유 식별자 (함수 이름 및 인수에 따라 다름)를 파일 이름 으로 사용하여 결과를 파일로 피클합니다 . 연속 실행시 피클 된 개체가로드됩니다.

이 경우 cachedir파이썬 실행 사이의 보존, 절임 객체는 이전 파이썬 실행에서 가져옵니다.

함수 인수도 고려됩니다. 리팩토링 된 구현은 다음과 같이 작동합니다.

from anycache import anycache

class Fruits:pass

@anycache(cachedir='/path/to/your/cache')
def myfunc(color, value)
    fruit = Fruits()
    fruit.color = color
    fruit.value = value
return fruit