Search code examples
pythonformatreadability

Python: Best way to declare more than one keys in a shelf


Context: I'm trying to practice shelves in python and wanted to make the most basic program to try out methods.

I wrote this code:

#creates a shelf, with 3 set keys and 3 input values then prints it

import shelve

settings_shelf = shelve.open('TempData')

settings_shelf['volume'] = input()
settings_shelf['graphics'] = input()
settings_shelf['auto-save'] = input()

print(list(settings_shelf.keys())+ list(" ") + list(settings_shelf.values()))

settings_shelf.close()

Is there a better way to format this? instead of having 3 lines for inputs? I found this: Any way to use a tuple as key in a shelf? (Python) but I didn't really understand the answer..

I tried settings_shelf['volume','graphics'] = input(),input() but it throws out this error: even though it accepts the two inputs Traceback (most recent call last):

File "C:\Users\Simone\dev\Automate The Boring Stuff with Python\shelves.py", line 5, in settings_shelf['volume','graphics'] = input(),input() File "C:\Users\Simone\AppData\Local\Programs\Python\Python310\lib\shelve.py", line 125, in setitem self.dict[key.encode(self.keyencoding)] = f.getvalue() AttributeError: 'tuple' object has no attribute 'encode'

I tried adding print(tuple(xyz)) but still doesn't work.

Also.. would it be possible to write something like settings_shelf[input() = input() ? I tried this aswell but it messes up the end result it switches the last key and value


Solution

  • From shelve docs:

    The keys are ordinary strings.

    So you need to convert tuple to string, and convert it back later if needed.

    It't easier to use lists and json module

    Here is the example:

    import json
    import shelve
    
    settings_shelf = shelve.open('TempData')
    
    obj = {
        'volume': 123,
        'graphics': 456,
        'auto-save': True,
    }
    
    folder, name = 'some', 'obj'
    
    # Convert list to string
    obj_key = json.dumps([folder, name])
    print(obj_key)
    # => '["some", "obj"]'
    
    settings_shelf[obj_key] = obj
    
    print(settings_shelf[obj_key])
    # => {'volume': 123, 'graphics': 456, 'auto-save': True}
    
    # Convert string back to objects
    folder, name = json.loads(obj_key)
    print(folder, name)
    # => 'some obj'