title: Best approach to modify instance variable after running each method of a class?
body: <p>I am working on a data analysis application in Python. I have a <code>DataAttributes</code> class that provides various details of a dataset. However, in obtaining some of these values, it uses another set of methods that directly modifies the data - my <code>DataManipulator</code> class. </p>
  
  <p>To keep things simple for adding future methods to each class, I want to be able to reset the dataset to its original state AFTER running a method from <code>DataAttributes</code>. So this involves:</p>
  
  <ul>
  <li>Storing the initial state of the dataset</li>
  <li>Running a method from an instance of type <code>DataAttributes</code></li>
  <li>Resetting dataset to initial state</li>
  </ul>
  
  <p>Of course I could accomplish this by running a method at the beginning and end of each <code>DataAttributes</code> method, but that feels extremely clunky, especially given that there are dozens of methods for obtaining data attributes. What is a clean way of implementing this? I have looked into making a metaclass, but am unsure of how to modify instance variables using that approach. I've also looked into decorators, but am not sure if that's best either. </p>
  
  <p>In terms of an example of what I want to achieve, I want to do what is done below, but for "n" methods. Also, this is a vast simplification of what I'm working on - let's just pretend I have a good reason for what I'm doing, I know that conceptually, this example makes little sense. It's just meant to demonstrate what I want to achieve. </p>
  
  <pre><code>class MyClass():
      def __init__(self):
          self.mydata = np.array([1, 2, 3])
          self.my_initial_data = np.array([1, 2, 3])
  
      def store_initial_data(self):
          self.my_initial_data = np.array([1, 2, 3])
  
      def reset_data(self):
          self.mydata = self.my_initial_data
          print(self.mydata)
  
      def method_1(self):
          self.store_initial_data()
          self.mydata *= 2
          self.reset_data()
  
      def method_2(self):
          self.store_initial_data()
          self.mydata *= 2
          self.reset_data()
      .
      .
      .
  
      def method_n(self):
          self.store_initial_data()
          self.mydata *= 2
          self.reset_data()
  
  my_inst = MyClass()
  my_inst.method_1() # prints [1, 2, 3]
  </code></pre>