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


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=-1에 dump(); pickle그러면 기본 기록 (및 더 이전 버전과 호환되는) 프로토콜 대신 사용 가능한 최상의 프로토콜을 사용합니다. 이 경우 파일은 바이너리 모드 ( wb및 rb각각) 에서 열어야합니다 .

바이너리 모드는 기본 프로토콜이 바이너리 (즉, 텍스트가 아닌) 데이터 (쓰기 모드 '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

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


클라우드 서버에 로그인하는 단일 객체를 저장하고 싶습니다. 시간이 지남에 따라 여러 번 로그인하면 서버가 요청을 거부합니다. 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.