# `shelve` — Python object persistence

Source code: Lib/shelve.py

Un «estante» o shelve, es un objeto persistente similar a un diccionario. La diferencia con las bases de datos «dbm» es que los valores (¡no las claves!) en un estante pueden ser esencialmente objetos Python arbitrarios — cualquier cosa que el módulo `pickle` pueda manejar. Esto incluye la mayoría de las instancias de clase, tipos de datos recursivos y objetos que contienen muchos subobjetos compartidos. Las claves son cadenas ordinarias.

shelve.open(filename, flag='c', protocol=None, writeback=False, *, serializer=None, deserializer=None)

  Abre un diccionario persistente. El nombre de archivo especificado es el nombre de archivo base para la base de datos subyacente. Como efecto secundario, se puede agregar una extensión al nombre de archivo y se puede crear más de un archivo. De forma predeterminada, el archivo de base de datos subyacente se abre para leer y escribir. El parámetro opcional flag tiene la misma interpretación que el parámetro flag de `dbm.open()`.

  By default, pickles created with `pickle.DEFAULT_PROTOCOL` are used to serialize values. The version of the pickle protocol can be specified with the protocol parameter.

  Debido a la semántica de Python, un estante no puede saber cuándo se modifica una entrada de diccionario persistente mutable. De forma predeterminada, los objetos modificados se escriben sólo cuando se asignan al estante (consulte Ejemplo). Si el parámetro opcional writeback se establece en `True`, todas las entradas a las que se accede también se almacenan en caché en la memoria y se vuelven a escribir en `sync()` y `close()`; esto puede hacer que sea más práctico mutar entradas mutables en el diccionario persistente, pero, si se accede a muchas entradas, puede consumir grandes cantidades de memoria para la memoria caché, y puede hacer que la operación de cierre sea muy lenta ya que todas las entradas a las que se accede se vuelven a escribir (no hay manera de determinar qué entradas a las que se accede son mutables, ni cuáles se mutaron realmente).

  By default, `shelve` uses `pickle.dumps()` and `pickle.loads()` for serializing and deserializing. This can be changed by supplying serializer and deserializer, respectively.

  The serializer argument must be a callable which takes an object `obj` and the protocol as inputs and returns the representation `obj` as a bytes-like object; the protocol value may be ignored by the serializer.

  The deserializer argument must be a callable which takes a serialized object given as a `bytes` object and returns the corresponding object.

  A `ShelveError` is raised if serializer is given but deserializer is not, or vice-versa.

  Distinto en la versión 3.10: `pickle.DEFAULT_PROTOCOL` is now used as the default pickle protocol.

  Distinto en la versión 3.11: Acepta path-like object por nombre de archivo.

  Distinto en la versión 3.15: Accepts custom serializer and deserializer functions in place of `pickle.dumps()` and `pickle.loads()`.

  Nota

  No confíe en que el estante se cerrará automáticamente; siempre llame a `close()` explícitamente cuando ya no lo necesite, o use `shelve.open()` como administrador de contexto:

      with shelve.open('spam') as db:
          db['eggs'] = 'eggs'

Advertencia

Because the `shelve` module is backed by `pickle`, it is insecure to load a shelf from an untrusted source. Like with pickle, loading a shelf can execute arbitrary code.

Shelf objects support most of the methods and operations supported by dictionaries (except copying, constructors and operators `|` and `|=`). This eases the transition from dictionary based scripts to those requiring persistent storage.

Se admiten dos métodos adicionales:

Shelf.sync()

  Write back all entries in the cache if the shelf was opened with writeback set to `True`. Also empty the cache and synchronize the persistent dictionary on disk, if feasible. This is called automatically when `reorganize()` is called or the shelf is closed with `close()`.

Shelf.reorganize()

  Calls `sync()` and attempts to shrink space used on disk by removing empty space resulting from deletions.

  Added in version 3.15.

Shelf.close()

  Sincronice y cierre el objeto persistente dict. Las operaciones en un estante cerrado fallarán con un `ValueError`.

Ver también

Persistent dictionary recipe with widely supported storage formats and having the speed of native dictionaries.

## Restricciones

- La elección de qué paquete de base de datos se utilizará (como `dbm.ndbm` o `dbm.gnu`) depende de la interfaz disponible. Por lo tanto, no es seguro abrir la base de datos directamente usando `dbm`. La base de datos también está (desafortunadamente) sujeta a las limitaciones de `dbm`, si se usa — esto significa que (la representación pickle de) los objetos almacenados en la base de datos debe ser bastante pequeña, y en casos raros las colisiones de claves pueden hacer que la base de datos rechace las actualizaciones.

- The `shelve` module does not support concurrent read/write access to shelved objects. (Multiple simultaneous read accesses are safe.) When a program has a shelf open for writing, no other program should have it open for reading or writing. Unix file locking can be used to solve this, but this differs across Unix versions and requires knowledge about the database implementation used.

- On macOS `dbm.ndbm` can silently corrupt the database file on updates, which can cause hard crashes when trying to read from the database.

- `Shelf.reorganize()` may not be available for all database packages and may temporarily increase resource usage (especially disk space) when called. Additionally, it will never run automatically and instead needs to be called explicitly.

class shelve.Shelf(dict, protocol=None, writeback=False, keyencoding='utf-8', *, serializer=None, deserializer=None)

  Una subclase de `collections.abc.MutableMapping` que almacena valores pickle en el objeto dict.

  By default, pickles created with `pickle.DEFAULT_PROTOCOL` are used to serialize values. The version of the pickle protocol can be specified with the protocol parameter. See the `pickle` documentation for a discussion of the pickle protocols.

  Si el parámetro writeback es `True`, el objeto mantendrá un caché de todas las entradas a las que se accedió y las volverá a escribir en el dict en las horas de sincronización y cierre. Esto permite operaciones naturales en entradas mutables, pero puede consumir mucha más memoria y hacer que la sincronización y el cierre tomen mucho tiempo.

  El parámetro keyencoding es la codificación utilizada para codificar las claves antes de que se utilicen con el dict subyacente.

  The serializer and deserializer parameters have the same interpretation as in `open()`.

  El objeto `Shelf` también se puede utilizar como administrador de contexto, en cuyo caso se cerrará automáticamente cuando finalice el bloque `with`.

  Distinto en la versión 3.2: Se agregó el parámetro keyencoding; anteriormente, las claves siempre estaban codificadas en UTF-8.

  Distinto en la versión 3.4: Agregado soporte para administrador de contexto.

  Distinto en la versión 3.10: `pickle.DEFAULT_PROTOCOL` is now used as the default pickle protocol.

  Distinto en la versión 3.15: Added the serializer and deserializer parameters.

class shelve.BsdDbShelf(dict, protocol=None, writeback=False, keyencoding='utf-8', *, serializer=None, deserializer=None)

  A subclass of `Shelf` which exposes `first()`, `next()`, `previous()`, `last()` and `set_location()` methods. These are available in the third-party `bsddb` module from pybsddb but not in other database modules. The dict object passed to the constructor must support those methods. This is generally accomplished by calling one of `bsddb.hashopen()`, `bsddb.btopen()` or `bsddb.rnopen()`. The optional protocol, writeback, keyencoding, serializer and deserializer parameters have the same interpretation as in `open()`.

  Distinto en la versión 3.15: Added the serializer and deserializer parameters.

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

  A subclass of `Shelf` which accepts a filename instead of a dict-like object. The underlying file will be opened using `dbm.open()`. By default, the file will be created and opened for both read and write. The optional flag parameter has the same interpretation as for the `open()` function. The optional protocol, writeback, serializer and deserializer parameters have the same interpretation as in `open()`.

  Distinto en la versión 3.15: Added the serializer and deserializer parameters.

## Ejemplo

Para resumir la interfaz (`key` es una cadena de caracteres, `data` es un objeto arbitrario):

    import shelve

    d = shelve.open(filename)  # open -- file may get suffix added by low-level
                               # library

    d[key] = data              # store data at key (overwrites old data if
                               # using an existing key)
    data = d[key]              # retrieve a COPY of data at key (raise KeyError
                               # if no such key)
    del d[key]                 # delete data stored at key (raises KeyError
                               # if no such key)

    flag = key in d            # true if the key exists
    klist = list(d.keys())     # a list of all existing keys (slow!)

    # as d was opened WITHOUT writeback=True, beware:
    d['xx'] = [0, 1, 2]        # this works as expected, but...
    d['xx'].append(3)          # *this doesn't!* -- d['xx'] is STILL [0, 1, 2]!

    # having opened d without writeback=True, you need to code carefully:
    temp = d['xx']             # extracts the copy
    temp.append(5)             # mutates the copy
    d['xx'] = temp             # stores the copy right back, to persist it

    # or, d=shelve.open(filename,writeback=True) would let you just code
    # d['xx'].append(5) and have it work as expected, BUT it would also
    # consume more memory and make the d.close() operation slower.

    d.close()                  # close it

## Exceptions

exception shelve.ShelveError

  Exception raised when one of the arguments deserializer and serializer is missing in the `open()`, `Shelf`, `BsdDbShelf` and `DbfilenameShelf`.

  The deserializer and serializer arguments must be given together.

  Added in version 3.15.

Ver también

Módulo `dbm`

  Interfaz genérica para bases de datos estilo `dbm`.

Módulo `pickle`

  Object serialization used by `shelve`.