{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Пространства имен, области видимости" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## global" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "1\n" ] } ], "source": [ "a = 1\n", "\n", "def f():\n", " a = 2\n", " print(a)\n", "\n", "f()\n", "print(a)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "1\n" ] } ], "source": [ "a = 1\n", "\n", "def f():\n", " print(a)\n", "\n", "f()\n", "print(a)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "2\n" ] } ], "source": [ "a = 1\n", "\n", "def f():\n", " global a\n", " a = 2\n", " print(a)\n", "\n", "f()\n", "print(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## nonlocal" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n", "2\n", "1\n" ] } ], "source": [ "a = 1\n", "\n", "def f():\n", " a = 2\n", " def g():\n", " a = 3\n", " print(a)\n", "\n", " g()\n", " print(a)\n", "\n", "f()\n", "print(a)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n", "3\n", "1\n" ] } ], "source": [ "a = 1\n", "\n", "def f():\n", " a = 2\n", " def g():\n", " nonlocal a\n", " a = 3\n", " print(a)\n", "\n", " g()\n", " print(a)\n", "\n", "f()\n", "print(a)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "ename": "SyntaxError", "evalue": "no binding for nonlocal 'a' found (, line 5)", "output_type": "error", "traceback": [ "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m5\u001b[0m\n\u001b[0;31m nonlocal a\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m no binding for nonlocal 'a' found\n" ] } ], "source": [ "a = 1\n", "\n", "def f():\n", " def g():\n", " nonlocal a\n", " a = 3\n", " print(a)\n", "\n", " g()\n", " print(a)\n", "\n", "f()\n", "print(a)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n", "3\n", "3\n", "1\n" ] } ], "source": [ "a = 1\n", "\n", "def h():\n", " a = 2\n", " def f():\n", " def g():\n", " nonlocal a\n", " a = 3\n", " print(a)\n", "\n", " g()\n", " print(a)\n", "\n", " f()\n", " print(a)\n", "\n", "h()\n", "print(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Все вместе" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "After local assignment: test spam\n", "After nonlocal assignment: nonlocal spam\n", "After global assignment: nonlocal spam\n", "In global scope: global spam\n" ] } ], "source": [ "def scope_test():\n", " def do_local():\n", " spam = \"local spam\"\n", "\n", " def do_nonlocal():\n", " nonlocal spam\n", " spam = \"nonlocal spam\"\n", "\n", " def do_global():\n", " global spam\n", " spam = \"global spam\"\n", "\n", " spam = \"test spam\"\n", " do_local()\n", " print(\"After local assignment:\", spam)\n", " do_nonlocal()\n", " print(\"After nonlocal assignment:\", spam)\n", " do_global()\n", " print(\"After global assignment:\", spam)\n", "\n", "scope_test()\n", "print(\"In global scope:\", spam)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Новое локальное пространство имен создается только при вызове функции" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "if True:\n", " a = 1\n", "print(a)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n" ] } ], "source": [ "for i in range(3):\n", " a = 1\n", "print(a)\n", "print(i)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Время жизни объекта" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Счетчик ссылок" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "before f()\n", "start loop\n", "C(0) initialized\n", "end loop\n", "start loop\n", "C(1) initialized\n", "C(0) is about to be deleted\n", "end loop\n", "C(1) is about to be deleted\n", "after f()\n" ] } ], "source": [ "class C:\n", " def __init__(self, i):\n", " self.i = i\n", " print(\"C({}) initialized\".format(self.i))\n", "\n", " def __del__(self):\n", " print(\"C({}) is about to be deleted\".format(self.i))\n", "\n", "def f():\n", " for i in range(2):\n", " print(\"start loop\")\n", " o = C(i)\n", " print(\"end loop\")\n", "\n", "print(\"before f()\")\n", "f()\n", "print(\"after f()\")" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "C(1) initialized\n" ] }, { "data": { "text/plain": [ "2" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import sys\n", "\n", "x = C(1)\n", "sys.getrefcount(x)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y = x\n", "sys.getrefcount(x)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "del y\n", "sys.getrefcount(x)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import weakref\n", "\n", "y = weakref.proxy(x)\n", "sys.getrefcount(x)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y.i" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "C(1) is about to be deleted\n" ] }, { "ename": "ReferenceError", "evalue": "weakly-referenced object no longer exists", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mReferenceError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdel\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0my\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mReferenceError\u001b[0m: weakly-referenced object no longer exists" ] } ], "source": [ "del x\n", "y.i" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "C(2) initialized\n" ] }, { "data": { "text/plain": [ "2" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = C(2)\n", "sys.getrefcount(x)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x.x = x\n", "sys.getrefcount(x)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": true }, "outputs": [], "source": [ "y = weakref.proxy(x)\n", "del x" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "C(2) is about to be deleted\n" ] } ], "source": [ "y.x = None" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Циклические ссылки" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "init\n", "init\n", "done\n" ] } ], "source": [ "class Element:\n", " def __init__(self, data, prev=None, next=None):\n", " self.data = data\n", " self.prev = prev\n", " self.next = next\n", " print(\"init\")\n", "\n", " def __del__(self):\n", " print(\"del\", self.data)\n", "\n", "head = Element(1)\n", "tail = Element(2)\n", "head.next = tail\n", "tail.prev = head\n", "del head\n", "del tail\n", "print(\"done\")" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "init\n", "init\n", "del 2\n", "del 1\n", "done\n" ] } ], "source": [ "head = Element(1)\n", "tail = Element(2)\n", "head.next = tail\n", "tail.prev = head\n", "head.next = None\n", "del head\n", "del tail\n", "print(\"done\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.4.3" } }, "nbformat": 4, "nbformat_minor": 0 }