파이썬에서 여러 변수를 어떻게 저장하고 복원합니까?


104

약 12 개의 개체를 파일에 저장 한 다음 나중에 복원해야합니다. pickle 및 shelve와 함께 for 루프를 사용하려고 시도했지만 제대로 작동하지 않았습니다.

편집하다.
저장하려고했던 모든 객체가 같은 클래스에 있었는데 (이전에 언급 했어야했던) 다음과 같이 전체 클래스를 저장할 수 있다는 것을 몰랐습니다.

import pickle
def saveLoad(opt):
    global calc
    if opt == "save":
        f = file(filename, 'wb')
        pickle.dump(calc, f, 2)
        f.close
        print 'data saved'
    elif opt == "load":
        f = file(filename, 'rb')
        calc = pickle.load(f)
    else:
        print 'Invalid saveLoad option'

1
for 루프를 시도했다고 말합니다. 해당 코드와 "올바르게 작동하지 않는"이유 (즉, 무슨 일이 있었는지, 원하는 일이 무엇인지)를 게시하십시오.
Blair

Windows를 사용하는 경우 바이너리 모드로 파일을 열어야합니다.
John La Rooy 2011

@gnibbler : 바이너리 모드는 기본이 아닌 프로토콜 ( docs.python.org/library/pickle.html#usage ) 에만 필요합니다 .
Eric O Lebigot 2011

답변:


170

여러 객체를 저장해야하는 경우에는 간단히 단일 목록 또는 튜플에 넣을 수 있습니다. 예를 들면 다음과 같습니다.

import pickle

# obj0, obj1, obj2 are created here...

# Saving the objects:
with open('objs.pkl', 'w') as f:  # Python 3: open(..., 'wb')
    pickle.dump([obj0, obj1, obj2], f)

# Getting back the objects:
with open('objs.pkl') as f:  # Python 3: open(..., 'rb')
    obj0, obj1, obj2 = pickle.load(f)

당신은 많은 양의 데이터가있는 경우, 당신은 전달하여 파일 크기를 줄일 수 있습니다 protocol=-1dump(); pickle그러면 기본 기록 (및 더 이전 버전과 호환되는) 프로토콜 대신 사용 가능한 최상의 프로토콜을 사용합니다. 이 경우 파일은 바이너리 모드 ( wbrb각각) 에서 열어야합니다 .

바이너리 모드는 기본 프로토콜이 바이너리 (즉, 텍스트가 아닌) 데이터 (쓰기 모드 'wb'및 읽기 모드 'rb')를 생성하므로 Python 3에서도 사용해야합니다 .


12
Python 3.5에서는 파일을 "바이트"모드로 열어야했습니다 . 예를 들어 with open('objs.pickle', 'wb') as f:(참고 wb)
kbrose

안녕 @Eric, with open('objs.pkl') as f:단순히 비교 의 필요성은 무엇 obj1, obj2 = pickle.load(open("objs.pkl","rb"))입니까? 이 둘 사이에 차이점이 있습니까?
balandongiv

두 번째 양식에서는 파일을 닫지 않습니다. 병렬로 열 수있는 파일의 수는 일반적으로 운영 체제에 의해 상당히 제한되기 때문에 이는 좋은 방법으로 간주되지 않습니다 (파일을 닫지 않고 파일을 여는 루프를 시도하십시오!). 즉, 실제로 파일을 많이 열지 않을 때 파일을 닫지 않는 것이 작동하는 경우가 많습니다.
Eric O Lebigot

49

라는 내장 라이브러리가 pickle있습니다. 를 사용 pickle하면 객체를 파일로 덤프하고 나중에로드 할 수 있습니다.

import pickle

f = open('store.pckl', 'wb')
pickle.dump(obj, f)
f.close()

f = open('store.pckl', 'rb')
obj = pickle.load(f)
f.close()

1
I Python 3.4는 다음 f = open('store.pckl', 'wb')을 사용 하여 쓸 파일을 엽니 다. stackoverflow.com/questions/13906623/…을 참조하십시오. 그리고`f = open ( 'store.pckl', 'rb')를 사용하여 읽을 파일을 엽니 다. stackoverflow.com/questions/7031699/…를 참조하십시오 .
user3731622

3.4+에만 해당됩니까? 'b'를 사용하지 않으면 오류가 발생하기 때문에 거의 대답하지 못했습니다.
Wilmer E. Henao

12

shelvepickle 모듈을 살펴보아야 합니다. 많은 데이터를 저장해야하는 경우 데이터베이스를 사용하는 것이 좋습니다.


클라우드 서버에 로그인하는 단일 객체를 저장하고 싶습니다. 시간이 지남에 따라 여러 번 로그인하면 서버가 요청을 거부합니다. pickle 모듈을 사용하여 객체를 파일로 덤프하면 보안 문제가있을 수 있습니까? , 예를 들어 누군가가 내 덤프 된 객체를 얻으면 암호를 사용하지 않고 내 클라우드 스토리지에 로그인 할 수 있습니다.
alper

5

피클 파일에 여러 변수를 저장하는 또 다른 방법은 다음과 같습니다.

import pickle

a = 3; b = [11,223,435];
pickle.dump([a,b], open("trial.p", "wb"))

c,d = pickle.load(open("trial.p","rb"))

print(c,d) ## To verify

4

klepto메모리, 디스크 또는 데이터베이스에 대한 영구 캐싱을 제공하는을 사용할 수 있습니다 .

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('foo.txt')
>>> db['1'] = 1
>>> db['max'] = max
>>> squared = lambda x: x**2
>>> db['squared'] = squared
>>> def add(x,y):
...   return x+y
... 
>>> db['add'] = add
>>> class Foo(object):
...   y = 1
...   def bar(self, x):
...     return self.y + x
... 
>>> db['Foo'] = Foo
>>> f = Foo()
>>> db['f'] = f  
>>> 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('foo.txt')
>>> db
file_archive('foo.txt', {}, cached=True)
>>> db.load()
>>> db
file_archive('foo.txt', {'1': 1, 'add': <function add at 0x10610a0c8>, 'f': <__main__.Foo object at 0x10510ced0>, 'max': <built-in function max>, 'Foo': <class '__main__.Foo'>, 'squared': <function <lambda> at 0x10610a1b8>}, cached=True)
>>> db['add'](2,3)
5
>>> db['squared'](3)
9
>>> db['f'].bar(4)
5
>>> 

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


7
OP는 내장을 요구하지 않았습니다.
Mike McKerns

4

다음 접근 방식은 간단 해 보이며 크기가 다른 변수와 함께 사용할 수 있습니다.

import hickle as hkl
# write variables to filename [a,b,c can be of any size]
hkl.dump([a,b,c], filename)

# load variables from filename
a,b,c = hkl.load(filename)

hickle패키지는보다 강력하고 (오류 발생 가능성이 적음) pickle.
user2340939
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.