[Python-Leipzig] Dekoratoren im Notebook

Mike Müller mmueller at python-academy.de
Mi Jun 11 10:28:06 UTC 2014


Hallo Leipziger Python-Fans,

obwohl wir es gestern nicht geschafft haben die minimale
Menge des Outputs unserer Grill-Aktivitäten zu verzehren ;),
habe ich doch viele positive Rückmeldungen über unser Treffen
bekommen.

Anbei, wie versprochen, das Notebook mit den Ergebnissen unserer
Coding-Aktivitäten. Es ist noch genau so wie gestern entstanden,
also ohne Kommentare oder erklärenden Texte. Deshalb ist es für
Leute, die nicht beim Treffen waren, nur bedingt verständlich.
Ich denke mit ein paar Erläuterungen kann das auch allgemein
nützlich sein. Ich werde mich mal dran machen, etwas Prosa
dazu zu schreiben.

Wir suchen übrigens noch ein Vortragsthemen für unser Treffen
am 8. Juli. Ich werde an diesem Tag leider nicht da sein.
Der Treffpunkt steht aber zur Verfügung.

Viele Grüße
Mike
-------------- nächster Teil --------------
{
 "metadata": {
  "name": "",
  "signature": "sha256:eeae1e9d889adfed3b1bbb605b0dbc140b97cf8aa270f92afaf8408236f21691"
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "heading",
     "level": 1,
     "metadata": {},
     "source": [
      "Dekoratoren"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from __future__ import print_function"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 5
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "def add(a, b):\n",
      "    return a + b"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 1
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "class A(object):\n",
      "    def func(a, b):\n",
      "        return a + b\n",
      "    func = staticmethod(func)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 2
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "class A(object):\n",
      "    @staticmethod\n",
      "    def func(a, b):\n",
      "        return a + b"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 3
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "A.func(2, 3)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 4,
       "text": [
        "5"
       ]
      }
     ],
     "prompt_number": 4
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "def deco(func):\n",
      "    print('gerufen')\n",
      "    return func"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 6
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "@deco\n",
      "def add(a, b):\n",
      "    return a + b"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "gerufen\n"
       ]
      }
     ],
     "prompt_number": 16
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "def add(a, b):\n",
      "    a + b\n",
      "add = deco(add)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "gerufen\n"
       ]
      }
     ],
     "prompt_number": 8
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "def func(*args, **kwargs):\n",
      "    print(args)\n",
      "    print(kwargs)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 9
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "func(1, 2, a=10, b=20)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "(1, 2)\n",
        "{'a': 10, 'b': 20}\n"
       ]
      }
     ],
     "prompt_number": 11
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "add(*(20, 30))"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 17,
       "text": [
        "50"
       ]
      }
     ],
     "prompt_number": 17
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "add(**{'a':10, 'b':100})"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 20,
       "text": [
        "110"
       ]
      }
     ],
     "prompt_number": 20
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "import functools\n",
      "\n",
      "def hallo(func):\n",
      "    @functools.wraps(func)\n",
      "    def proxy(*args, **kwargs):\n",
      "        print('Hallo')\n",
      "        return func(*args, **kwargs)\n",
      "    proxy.__doc__ += ' noch mehr'\n",
      "    return proxy"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 39
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "@hallo\n",
      "def add(a, b):\n",
      "    \"\"\"Add two objects.\"\"\"\n",
      "    return a + b"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 40
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "add(3, 4)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Hallo\n"
       ]
      },
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 41,
       "text": [
        "7"
       ]
      }
     ],
     "prompt_number": 41
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "add.__name__"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 42,
       "text": [
        "'add'"
       ]
      }
     ],
     "prompt_number": 42
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "add.__doc__"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 43,
       "text": [
        "'Add two objects. noch mehr'"
       ]
      }
     ],
     "prompt_number": 43
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "def sage(wort):\n",
      "    def sage_(func):\n",
      "        @functools.wraps(func)\n",
      "        def proxy(*args, **kwargs):\n",
      "            print(wort)\n",
      "            return func(*args, **kwargs)\n",
      "        return proxy\n",
      "    return sage_"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 45
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "@sage('Hallo')\n",
      "@sage('Auf Wiedersehen')\n",
      "def add(a, b):\n",
      "    return a + b"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 49
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "add(3, 4)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Hallo\n",
        "Auf Wiedersehen\n"
       ]
      },
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 50,
       "text": [
        "7"
       ]
      }
     ],
     "prompt_number": 50
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "add = sage('Hallo')(add)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 51
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "import pickle\n",
      "\n",
      "def make_key(*args, **kwargs):\n",
      "    return pickle.dumps((args, kwargs))\n",
      "\n",
      "def cache(func):\n",
      "    c = {}\n",
      "    @functools.wraps(func)\n",
      "    def proxy(*args, **kwargs):\n",
      "        key = make_key(*args, **kwargs)\n",
      "        if key in c:\n",
      "            return c[key]\n",
      "        else:\n",
      "            res = func(*args, **kwargs)\n",
      "            c[key] = res\n",
      "            return res\n",
      "    return proxy"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 57
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "@cache\n",
      "def add(a, b):\n",
      "    print('addiere')\n",
      "    return a + b"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 58
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "add(2, 3)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "addiere\n"
       ]
      },
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 59,
       "text": [
        "5"
       ]
      }
     ],
     "prompt_number": 59
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "add(2, 3)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 60,
       "text": [
        "5"
       ]
      }
     ],
     "prompt_number": 60
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "add(2, 2)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "addiere\n"
       ]
      },
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 62,
       "text": [
        "4"
       ]
      }
     ],
     "prompt_number": 62
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "cell = add.__closure__[0]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 65
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "cell.cell_contents"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 66,
       "text": [
        "{'((I2\\nI2\\ntp0\\n(dp1\\ntp2\\n.': 4, '((I2\\nI3\\ntp0\\n(dp1\\ntp2\\n.': 5}"
       ]
      }
     ],
     "prompt_number": 66
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "pickle.loads('((I2\\nI2\\ntp0\\n(dp1\\ntp2\\n.')"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 67,
       "text": [
        "((2, 2), {})"
       ]
      }
     ],
     "prompt_number": 67
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "%timeit add(3, 7)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "addiere\n",
        "10000 loops, best of 3: 31.8 \u00b5s per loop"
       ]
      },
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "\n"
       ]
      }
     ],
     "prompt_number": 68
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "def cls_deco(cls):\n",
      "    print('dekoriere')\n",
      "    cls.xyz = 10\n",
      "    return cls"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 69
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "@cls_deco\n",
      "class A(object):\n",
      "    pass"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "dekoriere\n"
       ]
      }
     ],
     "prompt_number": 70
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "A.xyz"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 71,
       "text": [
        "10"
       ]
      }
     ],
     "prompt_number": 71
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "def insp(cls):\n",
      "    print(cls.__dict__)\n",
      "    return cls"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 73
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "@insp\n",
      "class B(object):\n",
      "    def meth1(self):\n",
      "        return 42"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "{'__dict__': <attribute '__dict__' of 'B' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'B' objects>, '__doc__': None, 'meth1': <function meth1 at 0x10485a938>}\n"
       ]
      }
     ],
     "prompt_number": 74
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "DEBUG = True\n",
      "def deco(func):\n",
      "    if not DEBUG:\n",
      "        return func\n",
      "    def "
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "ename": "SyntaxError",
       "evalue": "invalid syntax (<ipython-input-75-dabfd47dbabe>, line 5)",
       "output_type": "pyerr",
       "traceback": [
        "\u001b[0;36m  File \u001b[0;32m\"<ipython-input-75-dabfd47dbabe>\"\u001b[0;36m, line \u001b[0;32m5\u001b[0m\n\u001b[0;31m    def\u001b[0m\n\u001b[0m        ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
       ]
      }
     ],
     "prompt_number": 75
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "\n",
      "def add(a, b):\n",
      "    return a + b"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 78
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "%save add.py _i78"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "The following commands were written to file `add.py`:\n",
        "\n",
        "def add(a, b):\n",
        "    return a + b\n"
       ]
      }
     ],
     "prompt_number": 84
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "open('add.py').read()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 86,
       "text": [
        "'# coding: utf-8\\n\\ndef add(a, b):\\n    return a + b\\n'"
       ]
      }
     ],
     "prompt_number": 86
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "import add"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 87
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "add.add(3, 4)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 88,
       "text": [
        "7"
       ]
      }
     ],
     "prompt_number": 88
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "def func():\n",
      "    return 'Hallo'"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 89
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "%save func.py _i89"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "The following commands were written to file `func.py`:\n",
        "def func():\n",
        "    return 'Hallo'\n"
       ]
      }
     ],
     "prompt_number": 90
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "ls"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Dekoratoren.ipynb  add.py             add.pyc            func.py\r\n"
       ]
      }
     ],
     "prompt_number": 91
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "import os\n",
      "\n",
      "def get_func(dir_=os.getcwd()):\n",
      "    func_texts = {}\n",
      "    mods = {}\n",
      "    for fn in os.listdir(dir_):\n",
      "        if fn.endswith('.py'):\n",
      "            name = os.path.splitext(fn)[0]\n",
      "            with open(os.path.join(dir_, fn)) as fobj:\n",
      "                func_texts[name] = fobj.read()\n",
      "                mods[name] = __import__(name)\n",
      "                \n",
      "    return func_texts, mods"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 102
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "f = get_func()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 103
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "f[0]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 104,
       "text": [
        "{'add': '# coding: utf-8\\n\\ndef add(a, b):\\n    return a + b\\n',\n",
        " 'func': \"# coding: utf-8\\ndef func():\\n    return 'Hallo'\\n\"}"
       ]
      }
     ],
     "prompt_number": 104
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "f[1]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 105,
       "text": [
        "{'add': <module 'add' from 'add.py'>, 'func': <module 'func' from 'func.py'>}"
       ]
      }
     ],
     "prompt_number": 105
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "f[1]['add'].add(2, 3)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 106,
       "text": [
        "5"
       ]
      }
     ],
     "prompt_number": 106
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [],
     "language": "python",
     "metadata": {},
     "outputs": []
    }
   ],
   "metadata": {}
  }
 ]
}


Mehr Informationen über die Mailingliste Python-Leipzig