shelve --- Tính bền vững của đối tượng Python¶
Source code: Lib/shelve.py
"Kệ" là một vật thể cố định, giống như từ điển. Sự khác biệt với cơ sở dữ liệu "dbm" là các giá trị (không phải khóa!) trong một giá về cơ bản có thể là các đối tượng Python tùy ý --- bất kỳ thứ gì mà mô-đun pickle có thể xử lý. Điều này bao gồm hầu hết các thể hiện của lớp, kiểu dữ liệu đệ quy và các đối tượng chứa nhiều đối tượng con được chia sẻ. Các phím là các chuỗi thông thường.
- shelve.open(filename, flag='c', protocol=None, writeback=False)¶
Mở một từ điển liên tục. Tên tệp được chỉ định là tên tệp cơ sở cho cơ sở dữ liệu cơ bản. Là một tác dụng phụ, phần mở rộng có thể được thêm vào tên tệp và nhiều tệp có thể được tạo. Theo mặc định, tệp cơ sở dữ liệu cơ bản được mở để đọc và ghi. Tham số flag tùy chọn có cách hiểu tương tự như tham số flag của
dbm.open().Theo mặc định, dưa chua được tạo bằng
pickle.DEFAULT_PROTOCOLđược sử dụng để tuần tự hóa các giá trị. Phiên bản của giao thức dưa chua có thể được chỉ định bằng tham số protocol.Do ngữ nghĩa của Python, một kệ không thể biết khi nào một mục nhập từ điển liên tục có thể thay đổi được sửa đổi. Theo mặc định, các đối tượng được sửa đổi được ghi only khi được gán vào giá (xem Ví dụ). Nếu tham số writeback tùy chọn được đặt thành
True, tất cả các mục được truy cập cũng được lưu vào bộ nhớ và được ghi lại trênsync()vàclose(); điều này có thể giúp việc thay đổi các mục có thể thay đổi trong từ điển liên tục trở nên dễ dàng hơn, tuy nhiên, nếu nhiều mục được truy cập, nó có thể tiêu tốn một lượng lớn bộ nhớ cho bộ nhớ đệm và có thể khiến thao tác đóng rất chậm vì tất cả các mục đã truy cập đều được ghi lại (không có cách nào để xác định mục đã truy cập nào có thể thay đổi cũng như mục nào thực sự đã bị thay đổi).Thay đổi trong phiên bản 3.10:
pickle.DEFAULT_PROTOCOLhiện được sử dụng làm giao thức dưa chua mặc định.Thay đổi trong phiên bản 3.11: Chấp nhận path-like object cho tên tệp.
Ghi chú
Đừng trông chờ vào việc kệ sẽ tự động đóng lại; luôn gọi
close()một cách rõ ràng khi bạn không cần nó nữa hoặc sử dụngshelve.open()làm trình quản lý bối cảnhvới shelve.open('spam') là db: db['trứng'] = 'trứng'
Cảnh báo
Vì mô-đun shelve được hỗ trợ bởi pickle nên việc tải giá từ một nguồn không đáng tin cậy là không an toàn. Giống như với dưa chua, việc tải giá có thể thực thi mã tùy ý.
Các đối tượng kệ hỗ trợ hầu hết các phương thức và thao tác được hỗ trợ bởi từ điển (ngoại trừ sao chép, hàm tạo và toán tử | và |=). Điều này giúp dễ dàng chuyển đổi từ các tập lệnh dựa trên từ điển sang các tập lệnh yêu cầu lưu trữ liên tục.
Hai phương pháp bổ sung được hỗ trợ:
- Shelf.sync()¶
Ghi lại tất cả các mục trong bộ đệm nếu giá được mở với writeback được đặt thành
True. Đồng thời làm trống bộ nhớ đệm và đồng bộ hóa từ điển liên tục trên đĩa nếu khả thi. Điều này được gọi tự động khi giá được đóng bằngclose().
- Shelf.close()¶
Đồng bộ hóa và đóng đối tượng dict liên tục. Các thao tác trên kệ đã đóng sẽ không thành công với
ValueError.
Xem thêm
Persistent dictionary recipe với các định dạng lưu trữ được hỗ trợ rộng rãi và có tốc độ của từ điển gốc.
Hạn chế¶
Việc lựa chọn gói cơ sở dữ liệu nào sẽ được sử dụng (chẳng hạn như
dbm.ndbmhoặcdbm.gnu) tùy thuộc vào giao diện nào có sẵn. Do đó, việc mở cơ sở dữ liệu trực tiếp bằngdbmlà không an toàn. Cơ sở dữ liệu cũng (không may) phải tuân theo các hạn chế củadbm, nếu nó được sử dụng --- điều này có nghĩa là (biểu diễn được chọn lọc của) các đối tượng được lưu trữ trong cơ sở dữ liệu sẽ khá nhỏ và trong một số trường hợp hiếm gặp, xung đột khóa có thể khiến cơ sở dữ liệu từ chối cập nhật.Mô-đun
shelvekhông hỗ trợ quyền truy cập đọc/ghi concurrent vào các đối tượng được sắp xếp. (Nhiều quyền truy cập đọc đồng thời là an toàn.) Khi một chương trình có giá mở để ghi thì không có chương trình nào khác được mở giá đó để đọc hoặc ghi. Khóa tệp Unix có thể được sử dụng để giải quyết vấn đề này, nhưng điều này khác nhau giữa các phiên bản Unix và yêu cầu kiến thức về cách triển khai cơ sở dữ liệu được sử dụng.Trên macOS
dbm.ndbmcó thể âm thầm làm hỏng tệp cơ sở dữ liệu khi cập nhật, điều này có thể gây ra sự cố nghiêm trọng khi cố đọc từ cơ sở dữ liệu.
- class shelve.Shelf(dict, protocol=None, writeback=False, keyencoding='utf-8')¶
Một lớp con của
collections.abc.MutableMappinglưu trữ các giá trị được chọn trong đối tượng dict.Theo mặc định, dưa chua được tạo bằng
pickle.DEFAULT_PROTOCOLđược sử dụng để tuần tự hóa các giá trị. Phiên bản của giao thức dưa chua có thể được chỉ định bằng tham số protocol. Xem tài liệupickleđể biết thảo luận về các giao thức dưa chua.Nếu tham số writeback là
True, đối tượng sẽ giữ bộ đệm của tất cả các mục được truy cập và ghi chúng trở lại dict vào thời điểm đồng bộ hóa và đóng. Điều này cho phép các hoạt động tự nhiên trên các mục có thể thay đổi, nhưng có thể tiêu tốn nhiều bộ nhớ hơn và khiến việc đồng bộ hóa và đóng mất nhiều thời gian.Tham số keyencoding là mã hóa được sử dụng để mã hóa các khóa trước khi chúng được sử dụng với lệnh cơ bản.
Đối tượng
Shelfcũng có thể được sử dụng làm trình quản lý bối cảnh, trong trường hợp đó, nó sẽ tự động bị đóng khi khốiwithkết thúc.Thay đổi trong phiên bản 3.2: Đã thêm tham số keyencoding; trước đây, các khóa luôn được mã hóa bằng UTF-8.
Thay đổi trong phiên bản 3.4: Đã thêm hỗ trợ quản lý bối cảnh.
Thay đổi trong phiên bản 3.10:
pickle.DEFAULT_PROTOCOLhiện được sử dụng làm giao thức dưa chua mặc định.
- class shelve.BsdDbShelf(dict, protocol=None, writeback=False, keyencoding='utf-8')¶
Một lớp con của
Shelfhiển thị các phương thứcfirst(),next(),previous(),last()vàset_location(). Những tính năng này có sẵn trong mô-đunbsddbcủa bên thứ ba từ pybsddb nhưng không có trong các mô-đun cơ sở dữ liệu khác. Đối tượng dict được truyền cho hàm tạo phải hỗ trợ các phương thức đó. Điều này thường được thực hiện bằng cách gọi một trong cácbsddb.hashopen(),bsddb.btopen()hoặcbsddb.rnopen(). Các tham số protocol, writeback và keyencoding tùy chọn có cách hiểu tương tự như đối với lớpShelf.
- class shelve.DbfilenameShelf(filename, flag='c', protocol=None, writeback=False)¶
Một lớp con của
Shelfchấp nhận filename thay vì một đối tượng giống như dict. Tệp cơ bản sẽ được mở bằngdbm.open(). Theo mặc định, file sẽ được tạo và mở cho cả đọc và ghi. Tham số flag tùy chọn có cách hiểu tương tự như đối với hàmopen(). Các tham số protocol và writeback tùy chọn có cách hiểu tương tự như đối với lớpShelf.
Ví dụ¶
Tóm tắt giao diện (key là một chuỗi, data là một đối tượng tùy ý):
kệ nhập khẩu
d = shelve.open(filename) # open -- file có thể được cấp thấp thêm hậu tố
# library
d[key] = data # store data at key (ghi đè dữ liệu cũ nếu
# using một khóa hiện có)
data = d[key] # retrieve một COPY dữ liệu tại khóa (tăng KeyError
# if không có phím đó)
del d[key] # delete dữ liệu được lưu trữ tại key (tăng KeyError
# if không có phím đó)
flag = key trong d # true nếu key tồn tại
klist = list(d.keys()) # a danh sách tất cả các khóa hiện có (chậm!)
# as d đã được mở WITHOUT writeback=Đúng, hãy cẩn thận:
d['xx'] = [0, 1, 2] # this hoạt động như mong đợi, nhưng...
d['xx'].append(3) # zz000zz -- d['xx'] là STILL [0, 1, 2]!
# having đã mở d mà không có writeback=Đúng, bạn cần viết mã cẩn thận:
temp = d['xx'] # extracts bản sao
temp.append(5) # mutates bản sao
d['xx'] = temp # stores sao chép lại ngay để duy trì nó
# or, d=shelve.open(filename,writeback=True) sẽ cho phép bạn viết mã
# d['xx'].append(5) và để nó hoạt động như mong đợi, BUT nó cũng sẽ như vậy
# consume có thêm bộ nhớ và làm cho thao tác d.close() chậm hơn.
d.close() # close nó