Created
August 31, 2016 05:55
-
-
Save jburroni/0a2db81ba541e1d8dc632368fd7f8982 to your computer and use it in GitHub Desktop.
a metaclass for python that keep tracks of created classes and instances. So, when one modifies a class, all the instantiated instances will refer to this new class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stderr", | |
"output_type": "stream", | |
"text": [ | |
"/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/__init__.py:872: UserWarning: axes.color_cycle is deprecated and replaced with axes.prop_cycle; please use the latter.\n", | |
" warnings.warn(self.msg_depr % (key, alt_key))\n" | |
] | |
} | |
], | |
"source": [ | |
"%matplotlib notebook" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 145, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"import weakref\n", | |
"from collections import defaultdict\n", | |
"import types" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 26, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"class Dict(dict):\n", | |
" pass" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 146, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"class class_holder(type):\n", | |
" classes = Dict()\n", | |
" all_instances = defaultdict(list)\n", | |
" def __init__(cls, name, bases, nmspc):\n", | |
" super(class_holder, cls).__init__(name, bases, nmspc)\n", | |
" \n", | |
" def instances(cls):\n", | |
" return [ref() for ref in class_holder.all_instances[name]]\n", | |
" \n", | |
" def pre_init(self, *args, **kargs):\n", | |
" answer = old_init(self, *args, **kargs)\n", | |
" class_holder.all_instances[name].append(weakref.ref(self))\n", | |
" return answer\n", | |
" old_init = cls.__init__\n", | |
" cls.__init__ = pre_init\n", | |
" cls.all_instances = types.MethodType(instances, cls, cls.__class__) \n", | |
" def adjust_instance(instance):\n", | |
" instance.__class__ = cls\n", | |
" return instance\n", | |
" def adjust_all_instances(instances):\n", | |
" to_remove = []\n", | |
" for id, reference in enumerate(instances):\n", | |
" instance = reference()\n", | |
" if instance:\n", | |
" adjust_instance(instance)\n", | |
" else: \n", | |
" to_remove.append(id)\n", | |
" [instances.remove(i) for i in to_remove[::-1]]\n", | |
" adjust_all_instances(class_holder.all_instances[name])\n", | |
" class_holder.classes[name] = weakref.ref(cls) " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 90, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"a = []" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 91, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]" | |
] | |
}, | |
"execution_count": 91, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"range(10)[::-1]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"[].remove" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 147, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"class Simple1(object):\n", | |
" __metaclass__ = class_holder\n", | |
" def foo(self):\n", | |
" print 'hola'\n", | |
" def bar(self): \n", | |
" print 'chau'" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 148, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"simple = Simple1()\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 149, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"hola\n" | |
] | |
} | |
], | |
"source": [ | |
"simple.foo()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 150, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"chau\n" | |
] | |
} | |
], | |
"source": [ | |
"simple.bar()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 151, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"class Simple1(object):\n", | |
" __metaclass__ = class_holder\n", | |
" def foo(self):\n", | |
" print 'hola'\n", | |
" def bar(self): \n", | |
" print 'goodbye'" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 152, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"goodbye\n" | |
] | |
} | |
], | |
"source": [ | |
"simple.bar()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 153, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"<bound method Simple1.bar of <__main__.Simple1 object at 0x112026850>>" | |
] | |
}, | |
"execution_count": 153, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"simple.bar" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 154, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"<__main__.Simple1 at 0x112026850>" | |
] | |
}, | |
"execution_count": 154, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"simple" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 155, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[<__main__.Simple1 at 0x112026850>]" | |
] | |
}, | |
"execution_count": 155, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"Simple1.all_instances()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 156, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"naranja = Simple1()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 157, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[<__main__.Simple1 at 0x112026850>, <__main__.Simple1 at 0x112026f90>]" | |
] | |
}, | |
"execution_count": 157, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"Simple1.all_instances()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 158, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"!open ." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 2", | |
"language": "python", | |
"name": "python2" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 2 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython2", | |
"version": "2.7.10" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment