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ên sync()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_PROTOCOL hiệ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ụng shelve.open() làm trình quản lý bối cảnh

với shelve.open('spam')  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ử ||=). Đ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ằng close().

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.ndbm hoặc dbm.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ằng dbm là 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ủa dbm, 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 shelve khô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.ndbm có 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.MutableMapping lư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ệu pickle để biết thảo luận về các giao thức dưa chua.

Nếu tham số writebackTrue, đố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 Shelf cũ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ối with kế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_PROTOCOL hiệ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 Shelf hiển thị các phương thức first(), next(), previous(), last()set_location(). Những tính năng này có sẵn trong mô-đun bsddb củ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ác bsddb.hashopen(), bsddb.btopen() hoặc bsddb.rnopen(). Các tham số protocol, writebackkeyencoding tùy chọn có cách hiểu tương tự như đối với lớp Shelf.

class shelve.DbfilenameShelf(filename, flag='c', protocol=None, writeback=False)

Một lớp con của Shelf chấp nhận filename thay vì một đối tượng giống như dict. Tệp cơ bản sẽ được mở bằng dbm.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àm open(). Các tham số protocolwriteback tùy chọn có cách hiểu tương tự như đối với lớp Shelf.

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ó

Xem thêm

Mô-đun dbm

Giao diện chung cho cơ sở dữ liệu kiểu dbm.

Mô-đun pickle

Tuần tự hóa đối tượng được sử dụng bởi shelve.