Skip to content

Instantly share code, notes, and snippets.

@abravalheri
Last active September 23, 2016 01:13
Show Gist options
  • Save abravalheri/50955f6c3af91063280f0ddac04ed2eb to your computer and use it in GitHub Desktop.
Save abravalheri/50955f6c3af91063280f0ddac04ed2eb to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--- metaclass ---\n"
]
}
],
"source": [
"print '--- metaclass ---'\n",
"class Meta(type):\n",
" def __new__(mcs, name, bases, attrs):\n",
" \"\"\"Meta.__new__\"\"\"\n",
" print 'Meta.__new__', mcs, name, bases, attrs\n",
"\n",
" # create properties dynamically\n",
" properties = attrs.pop('properties', [])\n",
" for prop in properties:\n",
" attrs[prop] = prop # make a property!\n",
"\n",
" return super(Meta, mcs).__new__(mcs, name, bases, attrs)\n",
" \n",
" def __init__(cls, name, bases, attrs):\n",
" \"\"\"Meta.__init__\"\"\"\n",
" print 'Meta.__init__', cls, name, bases, attrs\n",
" super(Meta, cls).__init__(name, bases, attrs)\n",
" \n",
" def __call__(cls, *args, **kwargs):\n",
" \"\"\"Meta.__call__\"\"\"\n",
" print 'Meta.__call__', cls, args, kwargs\n",
" \n",
" properties = kwargs.pop('properties', [])\n",
" if isinstance(properties, str):\n",
" properties = properties.split()\n",
" \n",
" # `properties` not passed... Use default behavior\n",
" if not properties:\n",
" return super(Meta, cls).__call__(*args, **kwargs)\n",
" \n",
" # Special behavior: construct a new class with `properties` attr\n",
" metaclass = cls.__class__\n",
" print '<<< BEGIN temporary class'\n",
" temp_class = metaclass(cls.__name__, (cls,), dict(properties=properties))\n",
" print '>>> END temporary class'\n",
" \n",
" return temp_class"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--- class ---\n",
"Meta.__new__ <class '__main__.Meta'> AClass (<type 'object'>,) {'__module__': '__main__', '__metaclass__': <class '__main__.Meta'>}\n",
"Meta.__init__ <class '__main__.AClass'> AClass (<type 'object'>,) {'__module__': '__main__', '__metaclass__': <class '__main__.Meta'>}\n"
]
}
],
"source": [
"print '--- class ---'\n",
"class AClass(object):\n",
" __metaclass__ = Meta"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"T.__new__(S, ...) -> a new object with type S, a subtype of T\n"
]
}
],
"source": [
"print AClass.__new__.__doc__"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--- object ---\n",
"Meta.__call__ <class '__main__.AClass'> () {}\n",
"<class '__main__.AClass'>\n"
]
}
],
"source": [
"print '--- object ---'\n",
"anobject = AClass()\n",
"print type(anobject)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--- class ---\n",
"Meta.__call__ <class '__main__.AClass'> () {'properties': ['a', 'b']}\n",
"<<< BEGIN temporary class\n",
"Meta.__new__ <class '__main__.Meta'> AClass (<class '__main__.AClass'>,) {'properties': ['a', 'b']}\n",
"Meta.__init__ <class '__main__.AClass'> AClass (<class '__main__.AClass'>,) {'a': 'a', 'b': 'b'}\n",
">>> END temporary class\n",
"<class '__main__.Meta'>\n"
]
}
],
"source": [
"print '--- class ---'\n",
"AnotherClass = AClass(properties=['a', 'b'])\n",
"print type(AnotherClass)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--- object ---\n",
"Meta.__call__ <class '__main__.AClass'> () {}\n",
"<class '__main__.AClass'>\n",
"a\n",
"b\n"
]
}
],
"source": [
"print '--- object ---'\n",
"x = AnotherClass()\n",
"print type(x)\n",
"print x.a\n",
"print x.b"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--- class ---\n",
"Meta.__new__ <class '__main__.Meta'> YetAnotherClass (<class '__main__.AClass'>,) {'__module__': '__main__', 'properties': ['c', 'd']}\n",
"Meta.__init__ <class '__main__.YetAnotherClass'> YetAnotherClass (<class '__main__.AClass'>,) {'__module__': '__main__', 'c': 'c', 'd': 'd'}\n",
"--- object ---\n",
"Meta.__call__ <class '__main__.YetAnotherClass'> () {}\n",
"c\n",
"d\n"
]
}
],
"source": [
"print '--- class ---'\n",
"class YetAnotherClass(AClass):\n",
" properties = ['c', 'd']\n",
"\n",
"print '--- object ---'\n",
"yetanotherobject = YetAnotherClass()\n",
"print yetanotherobject.c\n",
"print yetanotherobject.d"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--- class ---\n",
"Meta.__call__ <class '__main__.AClass'> () {'properties': ['e', 'f']}\n",
"<<< BEGIN temporary class\n",
"Meta.__new__ <class '__main__.Meta'> AClass (<class '__main__.AClass'>,) {'properties': ['e', 'f']}\n",
"Meta.__init__ <class '__main__.AClass'> AClass (<class '__main__.AClass'>,) {'e': 'e', 'f': 'f'}\n",
">>> END temporary class\n",
"Meta.__new__ <class '__main__.Meta'> OneMoreClass (<class '__main__.AClass'>,) {'__module__': '__main__'}\n",
"Meta.__init__ <class '__main__.OneMoreClass'> OneMoreClass (<class '__main__.AClass'>,) {'__module__': '__main__'}\n",
"--- object ---\n",
"Meta.__call__ <class '__main__.OneMoreClass'> () {}\n",
"e\n",
"f\n"
]
}
],
"source": [
"print '--- class ---'\n",
"class OneMoreClass(AClass(properties=['e', 'f'])):\n",
" pass\n",
"\n",
"\n",
"print '--- object ---'\n",
"onemoreobject = OneMoreClass()\n",
"print onemoreobject.e\n",
"print onemoreobject.f"
]
},
{
"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.11"
},
"widgets": {
"state": {},
"version": "1.1.2"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment