Search code examples
classpython-3.xshelve

Modifying class instances in Python


I have a small class:

import pickle
import shelve

class Base:

    def __init__(self, userid, username, pic_list=[]):
        self.userid=userid
        self.pic_list=pic_list
        self.username_list=[username]
        self.username=self.username_list[-1]

    def pic_add(self, pic):
        self.pic_list.append(pic)

if __name__ == '__main__':

    path="D:/"

    db = shelve.open(path+'test_base')

    db['111']=Base('111','111name',[4,5,6])
    db['111'].pic_add('123dsf')

    print (sorted(db['111'].pic_list))

    db.close()

I want to append 123dsf to pic_list of class instance "111". But the result I get is:

[4, 5, 6]
[Finished in 0.3s]

I want to receive [4, 5, 6, 123dsf]. What am I doing wrong?

Thanx.

P.S. Hint - It is something with shelve module syntax, 'cos adding 'y' works fine:

db['111']=Base('111','111name',[4,5,6])
db['111'].pic_add('123dsf')
Base.pic_add(db['111'],'123dsf')

y=Base('222','222name',[7,8,9])
y.pic_add('pis')

print (y.pic_list)

print (sorted(db['111'].pic_list))

The result is:

[7, 8, 9, 'pis']
[4, 5, 6]
[Finished in 0.4s]

Solution

  • Two ways to do it - as proposed in the documentation: https://docs.python.org/2/library/shelve.html#shelve-example

    1. set writeback flag:

    db = shelve.open(path+'test_base', writeback=True)
    

    allows you mutate objects in place:

    db['111'].pic_add('123dsf')
    

    2. Retrieve copy of stored object, then mutate copy, then store copy back:

    cpy = db['111']
    cpy.pic_add('123dsf')
    db['111'] = cpy