
Here is a non-trivial example of multiple dispatch. I want to convert data between container types, i.e. given into(a, b) I want to return something with the information content of b in a container like a, e.g. In [24]: into([], (1, 2, 3)) Out[24]: [1, 2, 3] We use this abstraction pretty heavily in Blaze, a project that tries to map relational algebra onto a variety of projects that might possibly be used to do relational-algebra-like tasks. Projects in this scope include sqlalchemy, pandas, numpy, pyspark, pytables, etc.. In [26]: from blaze import into A dataframe with some test data In [25]: df = DataFrame([[1, 'Alice', 100], [2, 'Bob', -200], [3, 'Charlie', 300], [4, 'Dennis', 400], [5, 'Edith', -500]], columns=['id', 'name', 'amount']) migrate list <- DataFrame In [27]: into([], df) Out[27]: [[1, 'Alice', 100], [2, 'Bob', -200], [3, 'Charlie', 300], [4, 'Dennis', 400], [5, 'Edith', -500]] migrate numpy array <- DataFrame In [28]: into(np.ndarray(0), df) Out[28]: rec.array([(1, 'Alice', 100), (2, 'Bob', -200), (3, 'Charlie', 300), (4, 'Dennis', 400), (5, 'Edith', -500)], dtype=[('id', '<i8'), ('name', 'O'), ('amount', '<i8')]) In [29]: x = into(np.ndarray(0), df) # store for later connect to local pymongo database In [30]: import pymongo In [31]: db = pymongo.MongoClient().db In [34]: into(db.my_collection, df) # migrate mongo <- pandas Out[34]: Collection(Database(MongoClient('localhost', 27017), u'db'), u'my_collection') In [35]: into(db.my_collection2, x) # migrate mongo <- numpy Out[35]: Collection(Database(MongoClient('localhost', 27017), u'db'), u'my_collection2') In [36]: list(db.my_collection2.find()) # verify that things transferred well Out[36]: [{u'_id': ObjectId('53ef6167fb5d1b34b9fd00e2'), u'amount': 100, u'id': 1, u'name': u'Alice'}, {u'_id': ObjectId('53ef6167fb5d1b34b9fd00e3'), u'amount': -200, u'id': 2, u'name': u'Bob'}, {u'_id': ObjectId('53ef6167fb5d1b34b9fd00e4'), u'amount': 300, u'id': 3, u'name': u'Charlie'}, {u'_id': ObjectId('53ef6167fb5d1b34b9fd00e5'), u'amount': 400, u'id': 4, u'name': u'Dennis'}, {u'_id': ObjectId('53ef6167fb5d1b34b9fd00e6'), u'amount': -500, u'id': 5, u'name': u'Edith'}] migrate bcolz <- mongo In [37]: into(bcolz.ctable(), db.my_collection) Out[37]: ctable((5,), [('amount', '<i8'), ('id', '<i8'), ('name', '<U7')]) nbytes: 220; cbytes: 63.99 KB; ratio: 0.00 cparams := cparams(clevel=5, shuffle=True, cname='blosclz') [(100, 1, u'Alice') (-200, 2, u'Bob') (300, 3, u'Charlie') (400, 4, u'Dennis') (-500, 5, u'Edith')] Note in this last case that the two libraries, bcolz (a compressed on-disk storage library) and pymongo know absolutely nothing about each other. Many of these into definitions are very simple @dispatch(np.ndarray, DataFrame) def into(a, df): return df.to_records(index=False) While some of them rely on others, or on inheritance @dispatch(Collection, np.ndarray) def into(coll, x, **kwargs): return into(coll, into(DataFrame(), x), **kwargs) But remembering all of the appropriate .to_foo and .from_bar methods can be a real pain. Collecting them all into a single abstraction cuts down significantly on the administrative burden of data migrations. On Sat, Aug 16, 2014 at 6:34 AM, Antoine Pitrou <antoine@python.org> wrote:
Le 15/08/2014 14:01, Guido van Rossum a écrit :
Please do write about non-toy examples!
Are you looking for examples using the multipledispatch library, or multiple dispatch in general?
As for multiple dispatch in general, Numba uses something which is morally one in order to select the right specialization of, say, an operator (for example to choose amongst '+ between int and int', '+ between numpy.datetime64 and numpy.timedelta64', '+ between numpy.timedelta64 and numpy.timedelta64', etc.).
Regards
Antoine.
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/