Created
August 18, 2013 10:11
-
-
Save astynax/6260911 to your computer and use it in GitHub Desktop.
Notebook для м/к по метапрограммированию
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
{ | |
"metadata": { | |
"name": "" | |
}, | |
"nbformat": 3, | |
"nbformat_minor": 0, | |
"worksheets": [ | |
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# \u041c\u0435\u0442\u0430\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 Python" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"\u041f\u043e\u0441\u0442\u0430\u0440\u0430\u0435\u043c\u0441\u044f \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c\n", | |
"\n", | |
"- function objects\n", | |
"- \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f\n", | |
"- \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u044b\n", | |
"- \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440\u044b\n", | |
"- \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u0430\u0446\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u043e\u0432\n", | |
"- \u043c\u0435\u0442\u0430\u043a\u043b\u0430\u0441\u0441\u044b" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e\n", | |
"def add(x, y):\n", | |
" \"\"\"\n", | |
" Add x to y\n", | |
" \"\"\"\n", | |
" return x + y" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 1 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"add.func_doc # \u0434\u043e\u043a-\u0441\u0438\u0442\u043e\u043a\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f/\u0437\u0430\u043f\u0438\u0441\u0438" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 2, | |
"text": [ | |
"'\\n Add x to y\\n '" | |
] | |
} | |
], | |
"prompt_number": 2 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"add.func_dict['adsd'] = 42 # \u0442\u0430\u043a\u0436\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\n", | |
"add.adsd" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 3, | |
"text": [ | |
"42" | |
] | |
} | |
], | |
"prompt_number": 3 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print add.func_defaults # \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u043f\u043e-\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0438 \u0444\u0443\u043d\u0446\u0438\u0438 \u043d\u0435\u0442" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"None\n" | |
] | |
} | |
], | |
"prompt_number": 4 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# \u043d\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0434\u0430\u043d\u043d\u043e\u0439,\n", | |
"# \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0439 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u043e-\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e\n", | |
"import new\n", | |
"add_w_def = new.function(\n", | |
" add.func_code, add.func_globals, 'add2', (0, 1))\n", | |
"print add_w_def(), add_w_def(41)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"1 42\n" | |
] | |
} | |
], | |
"prompt_number": 5 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## \u0417\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"a = 2\n", | |
"def f(b):\n", | |
" return a + b\n", | |
"a = 10\n", | |
"print f(0)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"10\n" | |
] | |
} | |
], | |
"prompt_number": 6 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"f.func_globals['a']\n", | |
"# \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \"a\" \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439, \u0434\u043b\u044f \u0444-\u0446\u0438\u0438 f,\n", | |
"# \u0442.\u043a. \u0438 \"a\" \u0438 \"f\" \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0432 \u0442\u043e\u043c \u0436\u0435 \u0444\u0440\u0435\u0439\u043c\u0435 \u0441\u0442\u0435\u043a\u0430,\n", | |
"# \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 7, | |
"text": [ | |
"10" | |
] | |
} | |
], | |
"prompt_number": 7 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def make_f(a):\n", | |
" def f(b):\n", | |
" return a + b\n", | |
" return f" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 8 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"f1 = make_f(42)\n", | |
"print f1(100), f1(10)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"142 52\n" | |
] | |
} | |
], | |
"prompt_number": 9 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print f1.func_closure\n", | |
"print f1.func_closure[0].cell_contents # \u0432\u043d\u0443\u0442\u0440\u0438 \u044f\u0447\u0435\u0439\u043a\u0438 \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u0439 - \u0437\u0430\u043c\u043a\u043d\u0443\u0442\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"(<cell at 0x931d9ec: int object at 0x8b3df04>,)\n", | |
"42\n" | |
] | |
} | |
], | |
"prompt_number": 10 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"f1.func_globals['a'] = 4564 # \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043d\u0435 \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u0435\n", | |
"f1(1)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 11, | |
"text": [ | |
"43" | |
] | |
} | |
], | |
"prompt_number": 11 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u0437\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u0438\n", | |
"def make_logger():\n", | |
" log = []\n", | |
" def write_to_log(s):\n", | |
" log.append(s)\n", | |
" def read_log():\n", | |
" return log[:]\n", | |
" return {'write': write_to_log, 'read': read_log}" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 12 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"log = make_logger()\n", | |
"log['write']('asdad')\n", | |
"log['write']('asdqweqw')\n", | |
"log['write'].func_closure[0].cell_contents" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 13, | |
"text": [ | |
"['asdad', 'asdqweqw']" | |
] | |
} | |
], | |
"prompt_number": 13 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print log['read']()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"['asdad', 'asdqweqw']\n" | |
] | |
} | |
], | |
"prompt_number": 14 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \"\u043f\u0440\u0438\u0432\u0430\u0442\u043d\u043e\u0441\u0442\u0438\" \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439\n", | |
"def make_class():\n", | |
" const = 42\n", | |
" class C(object):\n", | |
" def get(self):\n", | |
" return const\n", | |
" return C\n", | |
"C = make_class()\n", | |
"C().get()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 15, | |
"text": [ | |
"42" | |
] | |
} | |
], | |
"prompt_number": 15 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## \u0414\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u044b" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def dec(msg):\n", | |
" def wrapper(fn):\n", | |
" def inner(*args, **kwargs):\n", | |
" print msg\n", | |
" return fn(*args, **kwargs)\n", | |
" inner.func_doc = fn.func_doc\n", | |
" inner.func_name = fn.func_name\n", | |
" return inner\n", | |
" return wrapper" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 16 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"@dec(\"hello!\")\n", | |
"def f(a):\n", | |
" return a + 1\n", | |
"f(10)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"hello!\n" | |
] | |
}, | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 17, | |
"text": [ | |
"11" | |
] | |
} | |
], | |
"prompt_number": 17 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## \u0414\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440\u044b" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class ROValue(object):\n", | |
" \n", | |
" def __init__(self, att_name):\n", | |
" self._att_name = att_name\n", | |
" \n", | |
" def __get__(self, inst, cls):\n", | |
" assert inst, \"Thist is instance attr\"\n", | |
" return getattr(inst, self._att_name)\n", | |
" \n", | |
" def __set__(self, inst, value):\n", | |
" raise TypeError(\"Readonly!\")" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 18 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Our(object):\n", | |
" _a = 42\n", | |
" a = ROValue('_a')" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 19 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"Our().a" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 20, | |
"text": [ | |
"42" | |
] | |
} | |
], | |
"prompt_number": 20 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"our = Our()\n", | |
"our.a = 43" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"ename": "TypeError", | |
"evalue": "Readonly!", | |
"output_type": "pyerr", | |
"traceback": [ | |
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", | |
"\u001b[1;32m<ipython-input-21-ba09226d8ba8>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0mour\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mOur\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mour\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0ma\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m43\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", | |
"\u001b[1;32m<ipython-input-18-bbdf8e7bb55f>\u001b[0m in \u001b[0;36m__set__\u001b[1;34m(self, inst, value)\u001b[0m\n\u001b[0;32m 9\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 10\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m__set__\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0minst\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 11\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Readonly!\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", | |
"\u001b[1;31mTypeError\u001b[0m: Readonly!" | |
] | |
} | |
], | |
"prompt_number": 21 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Cached(object):\n", | |
" \n", | |
" def __init__(self, att_name, generate):\n", | |
" self._att_name = att_name\n", | |
" self._generate = generate\n", | |
" \n", | |
" def __get__(self, inst, cls):\n", | |
" assert inst, \"Thist is instance attr\"\n", | |
" if hasattr(inst, self._att_name):\n", | |
" return getattr(inst, self._att_name)\n", | |
" val = self._generate(inst)\n", | |
" setattr(inst, self._att_name, val)\n", | |
" return val\n", | |
" \n", | |
" def __set__(self, inst, value):\n", | |
" raise TypeError(\"Readonly!\")" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 22 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def very_slow(obj):\n", | |
" print \"Veryy slooow!\"\n", | |
" return 1\n", | |
"\n", | |
"class Our(object):\n", | |
" big_int = Cached('_big_int_cache', very_slow)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 23 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"o = Our()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 24 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"print o.big_int # \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0443\u0442\n", | |
"print o.big_int" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Veryy slooow!\n", | |
"1\n", | |
"1\n" | |
] | |
} | |
], | |
"prompt_number": 25 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class TypedAttr(object):\n", | |
" def __init__(self, attr_name, value_name, typ):\n", | |
" self._attr_name = attr_name\n", | |
" self._value_name = value_name\n", | |
" self._type = typ\n", | |
"\n", | |
" def __get__(self, inst, cls):\n", | |
" assert inst\n", | |
" return inst.__dict__[self._value_name]\n", | |
" \n", | |
" def __set__(self, inst, value):\n", | |
" assert inst\n", | |
" if not isinstance(value, self._type):\n", | |
" raise TypeError(\n", | |
" 'Value of attr \"%s\" must be %s' % (\n", | |
" self._attr_name, self._type\n", | |
" ))\n", | |
" inst.__dict__[self._value_name] = value" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 26 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class Point(object):\n", | |
" x = TypedAttr('x', '_x', int)\n", | |
" y = TypedAttr('y', '_y', int)\n" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 27 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"p = Point()\n", | |
"p.x = 10\n", | |
"p.y = \"asdasd\"" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"ename": "TypeError", | |
"evalue": "Value of attr \"y\" must be <type 'int'>", | |
"output_type": "pyerr", | |
"traceback": [ | |
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", | |
"\u001b[1;32m<ipython-input-28-ca4e8f3ca389>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0mp\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mPoint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[0mp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mx\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m10\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0my\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m\"asdasd\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", | |
"\u001b[1;32m<ipython-input-26-d9795cd9bdc5>\u001b[0m in \u001b[0;36m__set__\u001b[1;34m(self, inst, value)\u001b[0m\n\u001b[0;32m 14\u001b[0m raise TypeError(\n\u001b[0;32m 15\u001b[0m 'Value of attr \"%s\" must be %s' % (\n\u001b[1;32m---> 16\u001b[1;33m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_attr_name\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_type\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 17\u001b[0m ))\n\u001b[0;32m 18\u001b[0m \u001b[0minst\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__dict__\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_value_name\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mvalue\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", | |
"\u001b[1;31mTypeError\u001b[0m: Value of attr \"y\" must be <type 'int'>" | |
] | |
} | |
], | |
"prompt_number": 28 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## \u0414\u0435\u043a\u043e\u0440\u0430\u0446\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u043e\u0432" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def serializable(cls):\n", | |
" cls.to_str = lambda self: str(self)\n", | |
" return cls" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 29 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"@serializable\n", | |
"class C(object):\n", | |
" pass" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 30 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"C().to_str()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 31, | |
"text": [ | |
"'<__main__.C object at 0x93a68ac>'" | |
] | |
} | |
], | |
"prompt_number": 31 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## \u041c\u0435\u0442\u0430\u043a\u043b\u0430\u0441\u0441\u044b" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def with_defaults(name, bases, dic):\n", | |
" orig = dic['__init__']\n", | |
" dic['__init__'] = new.function(\n", | |
" orig.func_code,\n", | |
" orig.func_globals,\n", | |
" orig.func_name,\n", | |
" dic.get('_init_defaults', ())\n", | |
" )\n", | |
" return type(name, bases, dic)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 32 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class C(object):\n", | |
" __metaclass__ = with_defaults\n", | |
" \n", | |
" _init_defaults = (5, 6)\n", | |
" \n", | |
" def __init__(self, a, b):\n", | |
" print \"instantiated with args:\", a, b" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 33 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"c = C()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"instantiated with args: 5 6\n" | |
] | |
} | |
], | |
"prompt_number": 34 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"class D(C):\n", | |
" _init_defaults = (42, 24)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 35 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"d = D()" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"instantiated with args: 5 6\n" | |
] | |
} | |
], | |
"prompt_number": 33 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"\u041f\u0435\u0440\u0435\u043a\u0440\u044b\u0442\u0438\u0435 ```_init_defaults``` \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0430\u043b\u043e, \u0442.\u043a \u043c\u0435\u0442\u0430\u043a\u043b\u0430\u0441\u0441 \u0443\u0436\u0435 \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043b \u043e\u0434\u043d\u0430\u0436\u0434\u044b (\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044f ```\u0421```)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"*\u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0442\u0435\u043c\u0443*\n", | |
"\n", | |
"- [Python 3 Metaprogramming](https://www.youtube.com/watch?v=sPiWg5jSoZI)\n", | |
"- [Python Metaprogramming for Mad Scientists and Evil Geniuses](https://www.youtube.com/watch?v=Adr_QuDZxuM)" | |
] | |
} | |
], | |
"metadata": {} | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment