How to partially override/extend a Declarative class's constructor?
<p>These are the relevant bits of what I have:</p>

<pre><code>import sqlalchemy as db
import sqlalchemy.ext.declarative

Base = db.ext.declarative.declarative_base()

class Product(Base):
    __tablename__ = 'product'

    id = db.Column(db.Integer, primary_key=True)

class Bin(Base):
    __tablename__ = 'bin'

    id = db.Column(db.Integer, primary_key=True)
    product_id = db.Column(db.Integer, db.ForeignKey('product.id'), nullable=False)
    product = db.orm.relationship('Product')

class PurchaseItem(Base):
    __tablename__ = 'purchase_item'

    id = db.Column(db.Integer, primary_key=True)
    bin_id = db.Column(db.Integer, db.ForeignKey('bin.id'), nullable=False)
    bin = db.orm.relationship('Bin')
</code></pre>

<p>What I'd like is to have the <code>PurchaseItem</code> constructor automatically construct and use a <code>Bin</code> object if it's passed a <code>Product</code>. I'd normally do:</p>

<pre><code>def __init__(self, product=None, **kwargs):
    if product is not None:
        kwargs['bin'] = Bin(product=product)
    super(PurchaseItem, self).__init__(self, **kwargs)
</code></pre>

<p>, but I get this error:</p>

<pre><code>&gt;&gt;&gt; p = Product()
&gt;&gt;&gt; pi = PurchaseItem(product=p)
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  File "&lt;string&gt;", line 4, in __init__
  File "/Users/andrea/src/ifs/src/venv/lib/python2.7/site-packages/sqlalchemy/orm/state.py", line 306, in _initialize_instance
    manager.dispatch.init_failure(self, args, kwargs)
  File "/Users/andrea/src/ifs/src/venv/lib/python2.7/site-packages/sqlalchemy/util/langhelpers.py", line 60, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "/Users/andrea/src/ifs/src/venv/lib/python2.7/site-packages/sqlalchemy/orm/state.py", line 303, in _initialize_instance
    return manager.original_init(*mixed[1:], **kwargs)
  File "&lt;stdin&gt;", line 11, in __init__
TypeError: _declarative_constructor() takes exactly 1 argument (3 given)
</code></pre>

<p>presumably because <code>Base</code> is a metaclass and dynamically creates the subclass constructor.</p>

<p>I'm able to get what I want by storing the old constructor and creating a new one that then calls the old one:</p>

<pre><code>_old_init = PurchaseItem.__init__

def _new_init(self, product=None, init=_old_init, **kwargs):
    if product is not None:
        kwargs['bin'] = Bin(product=product)
    init(self, **kwargs)

PurchaseItem.__init__ = _new_init
</code></pre>

<p>Is there a way to do this in the <code>PurchaseItem</code> class definition? Failing that, is there a way that doesn't involve temporary variables ala emacs's <code>defadvice</code>?</p>