title: What is the best way to extend the functionality of an existing class of an existing 3rd party library?
body: <p>Lets say for example that I am using lots of <code>pandas.DataFrames</code> in my code.  This is a really big class with lots of pieces, and it has a very functional-like API to it, where you tend to chain its method calls together.</p>
  
  <p>It feels like it would be nice to easilly be able to add functionality to this existing class while still keeping the functional, flowing API in tact.</p>
  
  <p>I wanted to turn this class into something a bit domain-specific in the interests of removing a lot of domain-specific boilerplate code that is often used when using this class.</p>
  
  <p>Let's say in my dreams I'm to be able to do something like this:</p>
  
  <pre><code>pandas.read_csv('sales.csv') \
      .filter(items=['one', 'three']) \
      .apply(myTransformationFunction) \
      .saveToHivePartition(tablename = 'sales', partitionColumn = 'four') \
      .join(pandas.read_csv('employees.csv')) \
      .filter(items=['one','three','five']) \
      .saveToHivePartition(tablename = 'EmployeeMetrics', partitionColumn = 'ten')
  </code></pre>
  
  <p>In this example, <code>saveToHivePartition</code> is a custom method that does a lot of stuff to atomically save something to HDFS at the correct location and then adds that information tot he hive metadatastore.  Super useful!</p>
  
  <p>Obviously the "easy" answer is to simply create a standalone function that I can pass a <code>DataFrame</code> object into along with the other paramaters that I need.  Every time I want to perform the save, I need to encapsulate the dataframe into a variable and then pass that variable into a separate function.  Nowhere near as clean as the above example!</p>
  
  <p>So then the next thing that comes to mind is to create some cool new <code>SuperDataFrame</code> class that is a superset of <code>DataFrame</code>.  The only issue with that approach is: How do you even construct it?  i can't change <code>pandas.read_csv()</code> to start returning my new class.  I can't cast a base class into a subclass.  I could have <code>SuperDataFrame</code> be... a wrapper for the dataframe class?  But then I think that any time I want to call a base <code>DataFrame</code> function, It would have to be like this:</p>
  
  <pre><code>SuperDataFrame(pandas.read_csv('sales.csv')) \
      .df.filter .... \
      .df.apply .... \
      .saveToHivePartition .... \
      .df.join .... \
      .df.filter .... \
      .saveToHivepartition ....
  </code></pre>
  
  <p>I don't even think this works, because this assumes that whenever pandas performs a function, it mutates the <code>DataFrame</code> in-place, which I'm pretty sure it doesn't even do.</p>
  
  <p>Any ideas? Or is this just a bad thing?</p>