Search code examples
pythonclassoopdill

How to clone a class but not copy mutable attributes?


I am trying to write python code that will be able to track the created instances of a class, and save it through sessions. I am trying to to this by creating a list inside the class deceleration, which keeps track of instances. My code is as follows:

class test_object:
    _tracking = []

    def __init__(self, text):
        self.name = text
        test_object._tracking.insert(0, self)

with open("tst.pkl", mode="rb") as f:
    try:
        pickles = dill.load(f)
    except:
        pickles = test_object
        logger.warning("Found dill to be empty")
f.close()

My issue is handling when the pickled data is empty. What I'd like to do is in this case simply use the base class. The issue I'm running into is that test_object._tracking ends up being equal to pickles._tracking. Is there a way to make a copy of test_object so that when test_object._tracking gets updates, pickles._tracking stays the same?


Solution

  • You can do the following:

    import dill 
    
    class test_object:
        _tracking = []
    
        def __init__(self, text):
            self.name = text
            test_object._tracking.insert(0, self)
    
    test_1 = test_object("abc")
    print(test_object._tracking)
    # result: [<__main__.test_object object at 0x11a8cda50>]
    
    with open("./my_file.txt", mode="rb") as f:
        try:
            pickles = dill.load(f)
        except:
            pickles = type('test_object_copy', test_object.__bases__, dict(test_object.__dict__))
            pickles._tracking = []
    
            print("Found dill to be empty")
    # The above results in "Found dill to be empty"
    
    print(pickles._tracking)
    # prints []
    

    it'll set pickles to a copy of the original class. It's tracking attribute would then be empty, and would be different than the original 'tracking'.