Search code examples
pythonlistinstancesshelve

Python: Append to list owned by an instance stored in shelved dictionary


So I'm writing a script to keep track of my correspondence. It takes the name of someone who emailed me, looks for its associated 'Friend object' in a shelved dictionary of Friend instances (or creates itself a new instance and stores it in the dictionary), then appends the current time to that instance's list of timestamps.

So for example, if the script runs with 'John Citizen' as the input, it finds the key 'John Citizen' in the dictionary, gets the instance associated with that key, goes to that instance's list and appends to that list a timestamp.

This is all working as I want it to, except for the appending.

Here's the friend object:

class Friend():
    def __init__(self, name):
        self.name = name
        self.timestamps = []

    def add_timestamp(self, timestamp):
        self.timestamps.append(timestamp)   

Here's the global function that processes the input into a name string. (The input comes from AppleScript and is always in this format:

Input: "First [Middles] Last <[email protected]>"



def process_arguments():

    parser = argparse.ArgumentParser()
    parser.add_argument("sender", help="The output from AppleScript")
    args = parser.parse_args()
    full_name = args.sender

    ## gets just the name
    words = full_name.split(' ')
    words.pop()
    full_name = ' '.join(words)

    ## takes away all the non alpha characters, newlines etc.
    alpha_characters = []
    for character in full_name:
        if character.isalpha() or character == " ":
            alpha_characters.append(character)
    full_name = ''.join(alpha_characters)   
    return full_name

And then here's the script handling that full_name string.

  ## Get the timestamp and name
now = datetime.datetime.now()
full_name = process_arguments()

## open the shelf to store and access all the friend information

shelf = shelve.open('/Users/Perrin/Library/Scripts/friend_shelf.db')

if full_name in shelf:
    shelf[full_name].add_timestamp(now)
    shelf.close
else:
    shelf[full_name] = Friend(full_name)
    shelf.close

I've tried to debug it and full_name in shelf evaluates to True and the problem is still happening.

I just can't seem to get that self.timestamps list to populate. I would really appreciate any help!


Solution

  • You need to extract, mutate and store the object back in the shelf to persist it.

    e.g

    # extract
    this_friend = shelf[full_name]
    # mutate
    this_friend.add_timestamp(now)
    # re-add
    shelf[full_name] = this_friend
    shelf.close()
    

    You can see an example of this in the python docs.

    The other option is pass the writeback parameter as True to shelve.open and it will allow you to write to the keys directly.