Skip to content

Instantly share code, notes, and snippets.

@jburroni
Created August 31, 2016 05:55
Show Gist options
  • Save jburroni/0a2db81ba541e1d8dc632368fd7f8982 to your computer and use it in GitHub Desktop.
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
Display the source blob
Display the rendered blob
Raw
{
"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