shelve
--- 파이썬 객체 지속성¶
소스 코드: Lib/shelve.py
"쉘프(shelf)"는 영속적인(persistent) 딕셔너리류 객체입니다. "dbm" 데이터베이스와의 차이점은 쉘프의 값(키가 아닙니다!)이 사실상 임의의 파이썬 객체일 수 있다는 것입니다 --- pickle
모듈에서 처리할 수 있는 모든 것입니다. 여기에는 대부분의 클래스 인스턴스, 재귀적 데이터형 및 많은 공유 서브 객체를 포함하는 객체가 포함됩니다. 키는 일반 문자열입니다.
-
shelve.
open
(filename, flag='c', protocol=None, writeback=False)¶ 영속적 딕셔너리를 엽니다. 지정된 filename은 하부 데이터베이스의 기본 파일명입니다. 부작용으로, 확장명이 파일명에 추가될 수 있으며 여러 개의 파일이 만들어질 수 있습니다. 기본적으로, 하부 데이터베이스 파일은 읽기와 쓰기 용으로 열립니다. 선택적 flag 매개 변수는
dbm.open()
의 flag 매개 변수와 같게 해석됩니다.기본적으로, 값을 직렬화하는 데 버전 3 피클이 사용됩니다. 피클 프로토콜의 버전은 protocol 매개 변수로 지정할 수 있습니다.
파이썬 의미론 때문에, 쉘프는 가변 영속 딕셔너리 항목이 언제 수정되는지 알 수 없습니다. 기본적으로 수정된 객체는 쉘프에 대입될 때만 기록됩니다 (예제를 참조하십시오). 선택적인 writeback 매개 변수가
True
로 설정되면, 액세스 된 모든 항목도 메모리에 캐시 되고,sync()
와close()
가 호출될 때 다시 기록됩니다; 이것은 영속 딕셔너리의 가변 항목을 변경하는 것을 더 수월하게 만들지만, 많은 항목이 액세스 되면, 캐시를 위해 막대한 양의 메모리를 소비할 수 있으며, 액세스 된 모든 항목을 다시 기록하기 때문에 닫기 연산이 매우 느려질 수 있습니다 (어떤 액세스 된 항목이 가변인지, 어떤 것이 실제로 변경되었는지를 판별할 방법이 없습니다).참고
쉘프가 자동으로 닫히는 것에 의지하지 마십시오; 더는 필요 없을 때
close()
를 명시적으로 호출하거나,shelve.open()
을 컨텍스트 관리자로 사용하십시오:with shelve.open('spam') as db: db['eggs'] = 'eggs'
경고
shelve
모듈은 pickle
로 뒷받침되기 때문에, 신뢰할 수 없는 소스에서 쉘프를 로드하는 것은 안전하지 않습니다. 피클과 마찬가지로, 쉘프를 로드하면 임의의 코드를 실행할 수 있습니다.
쉘프 객체는 딕셔너리에서 지원하는 모든 메서드를 지원합니다. 이것은 딕셔너리 기반 스크립트에서 영속적인 저장소를 요구하는 것으로의 전환을 쉽게 만듭니다.
두 가지 추가 메서드가 지원됩니다:
-
Shelf.
sync
()¶ writeback을
True
로 설정하여 쉘프를 열었으면, 캐시의 모든 항목을 다시 기록합니다. 또한, 적절하다면, 캐시를 비우고 디스크 상의 영속 딕셔너리를 동기화합니다.close()
로 쉘프를 닫을 때 자동으로 호출됩니다.
-
Shelf.
close
()¶ 영구 딕셔너리 객체를 동기화하고 닫습니다. 닫힌 쉘프에 대한 연산은
ValueError
로 실패합니다.
더 보기
널리 지원되는 저장 형식과 기본 딕셔너리의 속도를 갖춘 Persistent dictionary recipe
제약 사항¶
사용되는 데이터베이스 패키지의 선택(가령
dbm.ndbm
이나dbm.gnu
)은 어떤 인터페이스가 사용 가능한지에 따라 다릅니다. 따라서dbm
을 사용하여 데이터베이스를 직접 여는 것은 안전하지 않습니다. 또한, 데이터베이스는 (불행히도)dbm
이 사용된다면 그것의 제약이 적용됩니다 --- 이것은 데이터베이스에 저장되는 객체(의 피클 된 표현이)가 상당히 작아야 하며, 드물긴 하지만 키 충돌로 인해 데이터베이스가 업데이트를 거부할 수 있음을 뜻합니다.shelve
모듈은 쉘브된 객체에 대한 동시성(concurrent) 읽기/쓰기 액세스를 지원하지 않습니다. (여러 동시적인 읽기 액세스는 안전합니다.) 어떤 프로그램이 쓰기 용으로 쉘프를 열고 있으면, 다른 어떤 프로그램도 읽기나 쓰기 용으로 열지 않아야 합니다. 유닉스 파일 잠금을 이 문제를 해결하는 데 사용할 수 있지만, 이것은 유닉스 버전마다 다르며 사용된 데이터베이스 구현에 대한 지식이 필요합니다.
-
class
shelve.
Shelf
(dict, protocol=None, writeback=False, keyencoding='utf-8')¶ dict 객체에 피클 된 값을 저장하는
collections.abc.MutableMapping
의 서브 클래스.기본적으로, 값을 직렬화하는 데 버전 3 피클이 사용됩니다. 피클 프로토콜의 버전은 protocol 매개 변수로 지정할 수 있습니다. 피클 프로토콜에 대한 설명은
pickle
설명서를 참조하십시오.writeback 매개 변수가
True
이면, 객체는 액세스 된 모든 항목의 캐시를 보유하고 sync와 close 할 때 dict에 다시 씁니다. 이것은 가변 항목에 대한 자연스러운 연산을 허락하지만, 더 많은 메모리를 소비하고 sync와 close 연산이 오래 걸릴 수 있습니다.keyencoding 매개 변수는 하부 dict에 사용되기 전에 키를 인코딩하는 데 사용되는 인코딩입니다.
Shelf
객체는 컨텍스트 관리자로 사용할 수도 있습니다. 이 경우with
블록이 끝날 때 자동으로 닫힙니다.버전 3.2에서 변경: keyencoding 매개 변수가 추가되었습니다; 이전에는 키가 항상 UTF-8으로 인코딩되었습니다.
버전 3.4에서 변경: 컨텍스트 관리자 지원 추가.
-
class
shelve.
BsdDbShelf
(dict, protocol=None, writeback=False, keyencoding='utf-8')¶ pybsddb의 제삼자
bsddb
모듈에서는 사용할 수 있지만 다른 데이터베이스 모듈에서는 사용할 수 없는first()
,next()
,previous()
,last()
및set_location()
을 노출하는Shelf
의 서브 클래스. 생성자에 전달된 dict 객체는 이러한 메서드를 지원해야 합니다. 이것은 일반적으로bsddb.hashopen()
,bsddb.btopen()
또는bsddb.rnopen()
중 하나를 호출하여 수행됩니다. 선택적 protocol, writeback 및 keyencoding 매개 변수는Shelf
클래스와 같게 해석됩니다.
-
class
shelve.
DbfilenameShelf
(filename, flag='c', protocol=None, writeback=False)¶ 딕셔너리류 객체 대신에 filename을 받아들이는
Shelf
의 서브 클래스. 하부 파일은dbm.open()
을 사용하여 열립니다. 기본적으로, 파일은 읽기와 쓰기가 가능하도록 만들어지고 열립니다. 선택적 flag 매개 변수는open()
기능과 같게 해석됩니다. 선택적 protocol과 writeback 매개 변수는Shelf
클래스와 같게 해석됩니다.
예제¶
인터페이스를 요약하면 (key
는 문자열입니다, data
는 임의의 객체입니다):
import shelve
d = shelve.open(filename) # 열기 -- 파일은 저수준 라이브러리에 의해 추가된 접미사를 얻을
# 수 있습니다
d[key] = data # 키에 데이터를 저장합니다 (기존 키를 사용하면 예전 데이터를
# 덮어씁니다)
data = d[key] # 키에서 데이터의 사본을 꺼냅니다 (그런 키가 없으면 KeyError를
# 발생시킵니다)
del d[key] # 키에 저장된 데이터를 삭제합니다 (그런 키가 없으면 KeyError를
# 발생시킵니다)
flag = key in d # 키가 존재하면 참입니다
klist = list(d.keys()) # 존재하는 모든 키의 리스트 (느립니다!)
# d가 writeback=True 없이 열렸으므로, 주의하십시오:
d['xx'] = [0, 1, 2] # 이것은 예상대로 작동합니다, 하지만...
d['xx'].append(3) # *이것은 그렇지 않습니다!* -- d['xx']는 여전히 [0, 1, 2]입니다!
# writeback=True 없이 열린 d에서는, 신중하게 코딩해야 합니다:
temp = d['xx'] # 사본을 꺼냅니다
temp.append(5) # 사본을 수정합니다
d['xx'] = temp # 영속적으로 만들기 위해, 사본을 다시 저장합니다
# 또는, d=shelve.open(filename,writeback=True)는 단지 d['xx'].append(5)로
# 코딩해도 기대한 대로 동작하게 만들지만, 더 많은 메모리를 소비하고 d.close() 연산을 더
# 느리게 만듭니다.
d.close() # 닫습니다